mirror of
https://github.com/Pecusx/libretro-atari800.git
synced 2026-05-21 21:33:56 +02:00
3110 lines
71 KiB
C
3110 lines
71 KiB
C
/*
|
|
* atari_x11.c - X11 specific port code
|
|
*
|
|
* Copyright (c) 1995-1998 David Firth
|
|
* Copyright (C) 1998-2014 Atari800 development team (see DOC/CREDITS)
|
|
*
|
|
* This file is part of the Atari800 emulator project which emulates
|
|
* the Atari 400, 800, 800XL, 130XE, and 5200 8-bit computers.
|
|
*
|
|
* Atari800 is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Atari800 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Atari800; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include "pokey.h"
|
|
|
|
#ifdef VMS
|
|
#include <stat.h>
|
|
#else
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
#include <signal.h>
|
|
#include <sys/time.h>
|
|
|
|
typedef unsigned char ubyte;
|
|
typedef unsigned short uword;
|
|
|
|
#ifdef XVIEW
|
|
#include <xview/xview.h>
|
|
#include <xview/frame.h>
|
|
#include <xview/panel.h>
|
|
#include <xview/canvas.h>
|
|
#include <xview/notice.h>
|
|
#include <xview/file_chsr.h>
|
|
#endif
|
|
|
|
#ifdef MOTIF
|
|
#include <Xm/MainW.h>
|
|
#include <Xm/DrawingA.h>
|
|
#include <Xm/MessageB.h>
|
|
#include <Xm/FileSB.h>
|
|
#include <Xm/RowColumn.h>
|
|
#include <Xm/ToggleBG.h>
|
|
|
|
static XtAppContext app;
|
|
static Widget toplevel;
|
|
static Widget main_w;
|
|
static Widget drawing_area;
|
|
static Widget fsel_b;
|
|
static Widget fsel_d;
|
|
static Widget fsel_r;
|
|
static Widget rbox_d;
|
|
static Widget togg_d1, togg_d2, togg_d3, togg_d4;
|
|
static Widget togg_d5, togg_d6, togg_d7, togg_d8;
|
|
static Widget eject_menu;
|
|
static Widget disable_menu;
|
|
static Widget system_menu;
|
|
static int motif_disk_sel = 1;
|
|
#endif /* MOTIF */
|
|
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
#include <X11/keysym.h>
|
|
|
|
#include "atari.h"
|
|
#include "binload.h"
|
|
#include "cartridge.h"
|
|
#include "colours.h"
|
|
#include "input.h"
|
|
#include "akey.h"
|
|
#include "log.h"
|
|
#include "monitor.h"
|
|
#include "memory.h"
|
|
#include "screen.h"
|
|
#include "sio.h"
|
|
#include "sound.h"
|
|
#include "platform.h"
|
|
#include "ui.h"
|
|
#include "util.h"
|
|
|
|
#ifdef SHM
|
|
#include <sys/ipc.h>
|
|
#include <sys/shm.h>
|
|
#include <X11/extensions/XShm.h>
|
|
|
|
static XShmSegmentInfo shminfo;
|
|
static XImage *image = NULL;
|
|
#ifdef USE_COLOUR_TRANSLATION_TABLE
|
|
extern int colour_translation_table[256];
|
|
#endif
|
|
#endif /* SHM */
|
|
|
|
static int invisible = 0;
|
|
|
|
#ifdef LINUX_JOYSTICK
|
|
#include <linux/joystick.h>
|
|
|
|
static int js0;
|
|
static int js1;
|
|
|
|
static int js0_centre_x;
|
|
static int js0_centre_y;
|
|
static int js1_centre_x;
|
|
static int js1_centre_y;
|
|
|
|
static struct JS_DATA_TYPE js_data;
|
|
#endif /* LINUX_JOYSTICK */
|
|
|
|
typedef enum {
|
|
Small,
|
|
Large,
|
|
Huge
|
|
} WindowSize;
|
|
|
|
static WindowSize windowsize = Large;
|
|
|
|
enum {
|
|
MONITOR_NOTHING,
|
|
MONITOR_SIO
|
|
} x11_monitor = MONITOR_NOTHING;
|
|
|
|
static int x11bug = FALSE;
|
|
static int private_cmap = FALSE;
|
|
|
|
static int window_width = 336;
|
|
static int window_height = Screen_HEIGHT;
|
|
|
|
static int clipping_factor = 1;
|
|
static int clipping_x = 24;
|
|
static int clipping_y = 0;
|
|
static int clipping_width = 336;
|
|
static int clipping_height = Screen_HEIGHT;
|
|
|
|
|
|
static Display *display = NULL;
|
|
static Screen *screen = NULL;
|
|
static Window window;
|
|
#ifndef SHM
|
|
static Pixmap pixmap;
|
|
#endif
|
|
static Visual *visual = NULL;
|
|
static Colormap cmap;
|
|
|
|
static GC gc;
|
|
static GC gc_colour[256];
|
|
static unsigned long colours[256];
|
|
static int colors_allocated;
|
|
static int force_redraw; /* flag for PLATFORM_DisplayScreen: redraw whole screen after a palette change */
|
|
|
|
#ifdef XVIEW
|
|
static Frame frame;
|
|
static Panel panel;
|
|
static Canvas canvas;
|
|
static Menu system_menu;
|
|
static Menu consol_menu;
|
|
static Menu options_menu;
|
|
static Frame chooser;
|
|
|
|
static Frame controllers_frame;
|
|
static Panel controllers_panel;
|
|
static Panel_item keypad_item;
|
|
static Panel_item mouse_item;
|
|
|
|
#ifdef LINUX_JOYSTICK
|
|
static Panel_item js0_item;
|
|
static Panel_item js1_item;
|
|
#endif
|
|
|
|
static Frame performance_frame;
|
|
static Panel performance_panel;
|
|
static Panel_item refresh_slider;
|
|
#endif /* XVIEW */
|
|
|
|
static int SHIFT = 0x00;
|
|
static int CONTROL = 0x00;
|
|
static UBYTE *image_data = NULL;
|
|
static int modified;
|
|
|
|
static int keypad_mode = -1; /* Joystick */
|
|
static int keypad_trig = 1; /* Keypad Trigger Position */
|
|
static int keypad_stick = 0x0f; /* Keypad Joystick Position */
|
|
|
|
static int xmouse_mode = -1; /* Joystick, Paddle and Light Pen */
|
|
static int mouse_stick; /* Mouse Joystick Position */
|
|
|
|
static int js0_mode = -1;
|
|
static int js1_mode = -1;
|
|
|
|
#ifndef SHM
|
|
|
|
#define NPOINTS (4096 / 4)
|
|
#define NRECTS (4096 / 4)
|
|
|
|
static XPoint points[NPOINTS];
|
|
static XRectangle rectangles[NRECTS];
|
|
#endif
|
|
|
|
static int keyboard_consol = INPUT_CONSOL_NONE;
|
|
static int menu_consol = INPUT_CONSOL_NONE;
|
|
|
|
static int autorepeat = 1;
|
|
static int last_focus = FocusOut;
|
|
|
|
static void autorepeat_get(void)
|
|
{
|
|
XKeyboardState kstat;
|
|
|
|
XGetKeyboardControl(display, &kstat);
|
|
autorepeat = kstat.global_auto_repeat;
|
|
}
|
|
|
|
static void autorepeat_off(void)
|
|
{
|
|
XAutoRepeatOff(display);
|
|
}
|
|
|
|
static void autorepeat_restore(void)
|
|
{
|
|
if (autorepeat)
|
|
XAutoRepeatOn(display);
|
|
else
|
|
XAutoRepeatOff(display);
|
|
}
|
|
|
|
static void segmentationfault(int x)
|
|
{
|
|
Atari800_ErrExit();
|
|
exit(0);
|
|
}
|
|
|
|
static int GetKeyCode(XEvent *event)
|
|
{
|
|
KeySym keysym;
|
|
char buffer[128];
|
|
static int keycode = AKEY_NONE;
|
|
|
|
if (event->type == KeyPress || event->type == KeyRelease) {
|
|
XLookupString((XKeyEvent *) event, buffer, sizeof(buffer), &keysym, NULL);
|
|
}
|
|
|
|
BINLOAD_pause_loading = FALSE;
|
|
|
|
switch (event->type) {
|
|
case Expose:
|
|
#ifndef SHM
|
|
XCopyArea(display, pixmap, window, gc,
|
|
0, 0,
|
|
window_width, window_height,
|
|
0, 0);
|
|
#else
|
|
modified = TRUE;
|
|
#endif
|
|
break;
|
|
case FocusIn:
|
|
autorepeat_off();
|
|
last_focus = FocusIn;
|
|
break;
|
|
case FocusOut:
|
|
autorepeat_restore();
|
|
last_focus = FocusOut;
|
|
break;
|
|
case VisibilityNotify:
|
|
if (((XVisibilityEvent*) event)->state == VisibilityFullyObscured)
|
|
invisible = 1;
|
|
else
|
|
invisible = 0;
|
|
break;
|
|
case KeyPress:
|
|
switch (keysym) {
|
|
case XK_Shift_L:
|
|
case XK_Shift_R:
|
|
SHIFT = AKEY_SHFT;
|
|
INPUT_key_shift = 1;
|
|
break;
|
|
case XK_Control_L:
|
|
keypad_trig = 0;
|
|
/* FALLTHROUGH */
|
|
case XK_Control_R:
|
|
CONTROL = AKEY_CTRL;
|
|
break;
|
|
case XK_F1:
|
|
keycode = AKEY_UI;
|
|
break;
|
|
case XK_F5:
|
|
case XK_L5:
|
|
keycode = SHIFT ? AKEY_COLDSTART : AKEY_WARMSTART;
|
|
break;
|
|
case XK_F8:
|
|
keycode = PLATFORM_Exit(TRUE) ? AKEY_NONE : AKEY_EXIT;
|
|
break;
|
|
case XK_F9:
|
|
keycode = AKEY_EXIT;
|
|
break;
|
|
case XK_F10:
|
|
case XK_L10:
|
|
keycode = SHIFT ? AKEY_SCREENSHOT_INTERLACE : AKEY_SCREENSHOT;
|
|
break;
|
|
case XK_F12:
|
|
keycode = AKEY_TURBO;
|
|
break;
|
|
case XK_Left:
|
|
keycode = AKEY_LEFT;
|
|
keypad_stick &= INPUT_STICK_LEFT;
|
|
break;
|
|
case XK_Up:
|
|
keycode = AKEY_UP;
|
|
keypad_stick &= INPUT_STICK_FORWARD;
|
|
break;
|
|
case XK_Right:
|
|
keycode = AKEY_RIGHT;
|
|
keypad_stick &= INPUT_STICK_RIGHT;
|
|
break;
|
|
case XK_Down:
|
|
keycode = AKEY_DOWN;
|
|
keypad_stick &= INPUT_STICK_BACK;
|
|
break;
|
|
case XK_KP_0:
|
|
keypad_trig = 0;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_1:
|
|
keypad_stick = INPUT_STICK_LL;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_2:
|
|
keypad_stick &= INPUT_STICK_BACK;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_3:
|
|
keypad_stick = INPUT_STICK_LR;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_4:
|
|
keypad_stick &= INPUT_STICK_LEFT;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_5:
|
|
keypad_stick = INPUT_STICK_CENTRE;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_6:
|
|
keypad_stick &= INPUT_STICK_RIGHT;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_7:
|
|
keypad_stick = INPUT_STICK_UL;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_8:
|
|
keypad_stick &= INPUT_STICK_FORWARD;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_KP_9:
|
|
keypad_stick = INPUT_STICK_UR;
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
}
|
|
if (Atari800_machine_type == Atari800_MACHINE_5200 && !UI_is_active) {
|
|
switch (keysym) {
|
|
case XK_F4:
|
|
keycode = SHIFT | AKEY_5200_START;
|
|
break;
|
|
case XK_P:
|
|
case XK_p:
|
|
keycode = SHIFT | AKEY_5200_PAUSE;
|
|
break;
|
|
case XK_R:
|
|
case XK_r:
|
|
keycode = SHIFT | AKEY_5200_RESET;
|
|
break;
|
|
case XK_0:
|
|
keycode = SHIFT | AKEY_5200_0;
|
|
break;
|
|
case XK_1:
|
|
keycode = SHIFT | AKEY_5200_1;
|
|
break;
|
|
case XK_2:
|
|
keycode = SHIFT | AKEY_5200_2;
|
|
break;
|
|
case XK_3:
|
|
keycode = SHIFT | AKEY_5200_3;
|
|
break;
|
|
case XK_4:
|
|
keycode = SHIFT | AKEY_5200_4;
|
|
break;
|
|
case XK_5:
|
|
keycode = SHIFT | AKEY_5200_5;
|
|
break;
|
|
case XK_6:
|
|
keycode = SHIFT | AKEY_5200_6;
|
|
break;
|
|
case XK_7:
|
|
keycode = SHIFT | AKEY_5200_7;
|
|
break;
|
|
case XK_8:
|
|
keycode = SHIFT | AKEY_5200_8;
|
|
break;
|
|
case XK_9:
|
|
keycode = SHIFT | AKEY_5200_9;
|
|
break;
|
|
/* XXX: "SHIFT | " harmful for '#' and '*' ? */
|
|
case XK_numbersign:
|
|
case XK_equal:
|
|
keycode = AKEY_5200_HASH;
|
|
break;
|
|
case XK_asterisk:
|
|
keycode = AKEY_5200_ASTERISK;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
switch (keysym) {
|
|
case XK_Caps_Lock:
|
|
keycode = SHIFT | CONTROL | AKEY_CAPSTOGGLE;
|
|
break;
|
|
case XK_Shift_Lock:
|
|
if (x11bug)
|
|
printf("XK_Shift_Lock\n");
|
|
break;
|
|
case XK_Alt_L:
|
|
case XK_Alt_R:
|
|
keycode = AKEY_ATARI;
|
|
break;
|
|
case XK_F2:
|
|
keyboard_consol &= (~INPUT_CONSOL_OPTION);
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_F3:
|
|
keyboard_consol &= (~INPUT_CONSOL_SELECT);
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_F4:
|
|
keyboard_consol &= (~INPUT_CONSOL_START);
|
|
keycode = AKEY_NONE;
|
|
break;
|
|
case XK_F6:
|
|
keycode = SHIFT | CONTROL | AKEY_HELP;
|
|
break;
|
|
case XK_Break:
|
|
case XK_F7:
|
|
if (BINLOAD_wait_active) {
|
|
BINLOAD_pause_loading = TRUE;
|
|
keycode = AKEY_NONE;
|
|
}
|
|
else
|
|
keycode = AKEY_BREAK;
|
|
break;
|
|
case XK_Home:
|
|
keycode = AKEY_CLEAR;
|
|
break;
|
|
case XK_Insert:
|
|
if (SHIFT)
|
|
keycode = AKEY_INSERT_LINE;
|
|
else
|
|
keycode = AKEY_INSERT_CHAR;
|
|
break;
|
|
case XK_BackSpace:
|
|
if (CONTROL)
|
|
keycode = AKEY_DELETE_CHAR;
|
|
else if (SHIFT)
|
|
keycode = AKEY_DELETE_LINE;
|
|
else
|
|
keycode = AKEY_BACKSPACE;
|
|
break;
|
|
case XK_Delete:
|
|
if (CONTROL)
|
|
keycode = AKEY_DELETE_CHAR;
|
|
else if (SHIFT)
|
|
keycode = AKEY_DELETE_LINE;
|
|
else
|
|
keycode = AKEY_BACKSPACE; /* XXX */
|
|
break;
|
|
case XK_End:
|
|
keycode = SHIFT | CONTROL | AKEY_HELP;
|
|
break;
|
|
case XK_Escape:
|
|
keycode = SHIFT | CONTROL | AKEY_ESCAPE;
|
|
break;
|
|
case XK_Tab:
|
|
keycode = SHIFT | CONTROL | AKEY_TAB;
|
|
break;
|
|
case XK_exclam:
|
|
keycode = CONTROL | AKEY_EXCLAMATION;
|
|
break;
|
|
case XK_quotedbl:
|
|
keycode = CONTROL | AKEY_DBLQUOTE;
|
|
break;
|
|
case XK_numbersign:
|
|
keycode = CONTROL | AKEY_HASH;
|
|
break;
|
|
case XK_dollar:
|
|
keycode = CONTROL | AKEY_DOLLAR;
|
|
break;
|
|
case XK_percent:
|
|
keycode = CONTROL | AKEY_PERCENT;
|
|
break;
|
|
case XK_ampersand:
|
|
keycode = CONTROL | AKEY_AMPERSAND;
|
|
break;
|
|
case XK_quoteright:
|
|
keycode = CONTROL | AKEY_QUOTE;
|
|
break;
|
|
case XK_at:
|
|
keycode = CONTROL | AKEY_AT;
|
|
break;
|
|
case XK_parenleft:
|
|
keycode = CONTROL | AKEY_PARENLEFT;
|
|
break;
|
|
case XK_parenright:
|
|
keycode = CONTROL | AKEY_PARENRIGHT;
|
|
break;
|
|
case XK_less:
|
|
keycode = CONTROL | AKEY_LESS;
|
|
break;
|
|
case XK_greater:
|
|
keycode = CONTROL | AKEY_GREATER;
|
|
break;
|
|
case XK_equal:
|
|
keycode = CONTROL | AKEY_EQUAL;
|
|
break;
|
|
case XK_question:
|
|
keycode = CONTROL | AKEY_QUESTION;
|
|
break;
|
|
case XK_minus:
|
|
keycode = CONTROL | AKEY_MINUS;
|
|
break;
|
|
case XK_plus:
|
|
keycode = CONTROL | AKEY_PLUS;
|
|
break;
|
|
case XK_asterisk:
|
|
keycode = CONTROL | AKEY_ASTERISK;
|
|
break;
|
|
case XK_slash:
|
|
keycode = CONTROL | AKEY_SLASH;
|
|
break;
|
|
case XK_colon:
|
|
keycode = CONTROL | AKEY_COLON;
|
|
break;
|
|
case XK_semicolon:
|
|
keycode = CONTROL | AKEY_SEMICOLON;
|
|
break;
|
|
case XK_comma:
|
|
keycode = CONTROL | AKEY_COMMA;
|
|
break;
|
|
case XK_period:
|
|
keycode = CONTROL | AKEY_FULLSTOP;
|
|
break;
|
|
case XK_underscore:
|
|
keycode = CONTROL | AKEY_UNDERSCORE;
|
|
break;
|
|
case XK_bracketleft:
|
|
keycode = CONTROL | AKEY_BRACKETLEFT;
|
|
break;
|
|
case XK_bracketright:
|
|
keycode = CONTROL | AKEY_BRACKETRIGHT;
|
|
break;
|
|
case XK_asciicircum:
|
|
keycode = CONTROL | AKEY_CIRCUMFLEX;
|
|
break;
|
|
case XK_backslash:
|
|
keycode = CONTROL | AKEY_BACKSLASH;
|
|
break;
|
|
case XK_bar:
|
|
keycode = CONTROL | AKEY_BAR;
|
|
break;
|
|
case XK_space:
|
|
keycode = SHIFT | CONTROL | AKEY_SPACE;
|
|
keypad_trig = 0;
|
|
break;
|
|
case XK_Return:
|
|
keycode = SHIFT | CONTROL | AKEY_RETURN;
|
|
keypad_stick = INPUT_STICK_CENTRE;
|
|
break;
|
|
case XK_0:
|
|
keycode = CONTROL | AKEY_0;
|
|
break;
|
|
case XK_1:
|
|
keycode = CONTROL | AKEY_1;
|
|
break;
|
|
case XK_2:
|
|
keycode = CONTROL | AKEY_2;
|
|
break;
|
|
case XK_3:
|
|
keycode = CONTROL | AKEY_3;
|
|
break;
|
|
case XK_4:
|
|
keycode = CONTROL | AKEY_4;
|
|
break;
|
|
case XK_5:
|
|
keycode = CONTROL | AKEY_5;
|
|
break;
|
|
case XK_6:
|
|
keycode = CONTROL | AKEY_6;
|
|
break;
|
|
case XK_7:
|
|
keycode = CONTROL | AKEY_7;
|
|
break;
|
|
case XK_8:
|
|
keycode = CONTROL | AKEY_8;
|
|
break;
|
|
case XK_9:
|
|
keycode = CONTROL | AKEY_9;
|
|
break;
|
|
case XK_A:
|
|
case XK_a:
|
|
keycode = SHIFT | CONTROL | AKEY_a;
|
|
break;
|
|
case XK_B:
|
|
case XK_b:
|
|
keycode = SHIFT | CONTROL | AKEY_b;
|
|
break;
|
|
case XK_C:
|
|
case XK_c:
|
|
keycode = SHIFT | CONTROL | AKEY_c;
|
|
break;
|
|
case XK_D:
|
|
case XK_d:
|
|
keycode = SHIFT | CONTROL | AKEY_d;
|
|
break;
|
|
case XK_E:
|
|
case XK_e:
|
|
keycode = SHIFT | CONTROL | AKEY_e;
|
|
break;
|
|
case XK_F:
|
|
case XK_f:
|
|
keycode = SHIFT | CONTROL | AKEY_f;
|
|
break;
|
|
case XK_G:
|
|
case XK_g:
|
|
keycode = SHIFT | CONTROL | AKEY_g;
|
|
break;
|
|
case XK_H:
|
|
case XK_h:
|
|
keycode = SHIFT | CONTROL | AKEY_h;
|
|
break;
|
|
case XK_I:
|
|
case XK_i:
|
|
keycode = SHIFT | CONTROL | AKEY_i;
|
|
break;
|
|
case XK_J:
|
|
case XK_j:
|
|
keycode = SHIFT | CONTROL | AKEY_j;
|
|
break;
|
|
case XK_K:
|
|
case XK_k:
|
|
keycode = SHIFT | CONTROL | AKEY_k;
|
|
break;
|
|
case XK_L:
|
|
case XK_l:
|
|
keycode = SHIFT | CONTROL | AKEY_l;
|
|
break;
|
|
case XK_M:
|
|
case XK_m:
|
|
keycode = SHIFT | CONTROL | AKEY_m;
|
|
break;
|
|
case XK_N:
|
|
case XK_n:
|
|
keycode = SHIFT | CONTROL | AKEY_n;
|
|
break;
|
|
case XK_O:
|
|
case XK_o:
|
|
keycode = SHIFT | CONTROL | AKEY_o;
|
|
break;
|
|
case XK_P:
|
|
case XK_p:
|
|
keycode = SHIFT | CONTROL | AKEY_p;
|
|
break;
|
|
case XK_Q:
|
|
case XK_q:
|
|
keycode = SHIFT | CONTROL | AKEY_q;
|
|
break;
|
|
case XK_R:
|
|
case XK_r:
|
|
keycode = SHIFT | CONTROL | AKEY_r;
|
|
break;
|
|
case XK_S:
|
|
case XK_s:
|
|
keycode = SHIFT | CONTROL | AKEY_s;
|
|
break;
|
|
case XK_T:
|
|
case XK_t:
|
|
keycode = SHIFT | CONTROL | AKEY_t;
|
|
break;
|
|
case XK_U:
|
|
case XK_u:
|
|
keycode = SHIFT | CONTROL | AKEY_u;
|
|
break;
|
|
case XK_V:
|
|
case XK_v:
|
|
keycode = SHIFT | CONTROL | AKEY_v;
|
|
break;
|
|
case XK_W:
|
|
case XK_w:
|
|
keycode = SHIFT | CONTROL | AKEY_w;
|
|
break;
|
|
case XK_X:
|
|
case XK_x:
|
|
keycode = SHIFT | CONTROL | AKEY_x;
|
|
break;
|
|
case XK_Y:
|
|
case XK_y:
|
|
keycode = SHIFT | CONTROL | AKEY_y;
|
|
break;
|
|
case XK_Z:
|
|
case XK_z:
|
|
keycode = SHIFT | CONTROL | AKEY_z;
|
|
break;
|
|
default:
|
|
if (x11bug)
|
|
printf("Pressed Keysym = %x\n", (int) keysym);
|
|
break;
|
|
}
|
|
break;
|
|
case KeyRelease:
|
|
keycode = AKEY_NONE;
|
|
switch (keysym) {
|
|
case XK_Shift_L:
|
|
case XK_Shift_R:
|
|
INPUT_key_shift = 0;
|
|
SHIFT = 0x00;
|
|
break;
|
|
case XK_Control_L:
|
|
keypad_trig = 1;
|
|
/* FALLTHROUGH */
|
|
case XK_Control_R:
|
|
CONTROL = 0x00;
|
|
break;
|
|
case XK_Shift_Lock:
|
|
if (x11bug)
|
|
printf("XK_Shift_Lock\n");
|
|
break;
|
|
case XK_F2:
|
|
keyboard_consol |= INPUT_CONSOL_OPTION;
|
|
break;
|
|
case XK_F3:
|
|
keyboard_consol |= INPUT_CONSOL_SELECT;
|
|
break;
|
|
case XK_F4:
|
|
keyboard_consol |= INPUT_CONSOL_START;
|
|
break;
|
|
case XK_space:
|
|
case XK_KP_0:
|
|
keypad_trig = 1;
|
|
break;
|
|
case XK_Down:
|
|
case XK_KP_2:
|
|
keypad_stick |= INPUT_STICK_CENTRE ^ INPUT_STICK_BACK;
|
|
break;
|
|
case XK_Left:
|
|
case XK_KP_4:
|
|
keypad_stick |= INPUT_STICK_CENTRE ^ INPUT_STICK_LEFT;
|
|
break;
|
|
case XK_Right:
|
|
case XK_KP_6:
|
|
keypad_stick |= INPUT_STICK_CENTRE ^ INPUT_STICK_RIGHT;
|
|
break;
|
|
case XK_Up:
|
|
case XK_KP_8:
|
|
keypad_stick |= INPUT_STICK_CENTRE ^ INPUT_STICK_FORWARD;
|
|
break;
|
|
case XK_KP_1:
|
|
case XK_KP_3:
|
|
case XK_KP_5:
|
|
case XK_KP_7:
|
|
case XK_KP_9:
|
|
keypad_stick = INPUT_STICK_CENTRE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return keycode;
|
|
}
|
|
|
|
#if defined(XVIEW) || defined(MOTIF)
|
|
|
|
static int insert_rom(const char *filename)
|
|
{
|
|
int r;
|
|
int i;
|
|
r = CARTRIDGE_Insert(filename);
|
|
if (r < 0)
|
|
return FALSE;
|
|
if (r == 0) {
|
|
Atari800_Coldstart();
|
|
return TRUE;
|
|
}
|
|
/* TODO: select cartridge type */
|
|
for (i = 1; i < CARTRIDGE_LAST_SUPPORTED; i++) {
|
|
if (CARTRIDGE_kb[i] == r) {
|
|
CARTRIDGE_main.type = i;
|
|
Atari800_Coldstart();
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static int xview_keycode = AKEY_NONE;
|
|
|
|
#endif /* defined(XVIEW) || defined(MOTIF) */
|
|
|
|
#ifdef XVIEW
|
|
|
|
static void event_proc(Xv_Window window, Event * event, Notify_arg arg)
|
|
{
|
|
xview_keycode = GetKeyCode(event->ie_xevent);
|
|
}
|
|
|
|
static int auto_reboot;
|
|
|
|
static int disk_change(char *a, char *full_filename, char *filename)
|
|
{
|
|
int diskno;
|
|
int status;
|
|
|
|
diskno = 1;
|
|
|
|
if (!auto_reboot)
|
|
diskno = notice_prompt(panel, NULL,
|
|
NOTICE_MESSAGE_STRINGS,
|
|
"Insert Disk into which drive?",
|
|
NULL,
|
|
NOTICE_BUTTON, "1", 1,
|
|
NOTICE_BUTTON, "2", 2,
|
|
NOTICE_BUTTON, "3", 3,
|
|
NOTICE_BUTTON, "4", 4,
|
|
NOTICE_BUTTON, "5", 5,
|
|
NOTICE_BUTTON, "6", 6,
|
|
NOTICE_BUTTON, "7", 7,
|
|
NOTICE_BUTTON, "8", 8,
|
|
NULL);
|
|
|
|
if ((diskno < 1) || (diskno > 8)) {
|
|
printf("Invalid diskno: %d\n", diskno);
|
|
exit(1);
|
|
}
|
|
SIO_Dismount(diskno);
|
|
if (!SIO_Mount(diskno, full_filename, FALSE))
|
|
status = XV_ERROR;
|
|
else {
|
|
if (auto_reboot)
|
|
Atari800_Coldstart();
|
|
status = XV_OK;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
static void boot_callback(void)
|
|
{
|
|
static char dir[FILENAME_MAX];
|
|
if (UI_n_atari_files_dir > 0)
|
|
strcpy(dir, UI_atari_files_dir[0]);
|
|
else
|
|
dir[0] = '\0';
|
|
auto_reboot = TRUE;
|
|
xv_set(chooser,
|
|
FRAME_LABEL, "Disk Selector",
|
|
FILE_CHOOSER_DIRECTORY, dir,
|
|
FILE_CHOOSER_NOTIFY_FUNC, disk_change,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
static void insert_callback(void)
|
|
{
|
|
static char dir[FILENAME_MAX];
|
|
if (UI_n_atari_files_dir > 0)
|
|
strcpy(dir, UI_atari_files_dir[0]);
|
|
else
|
|
dir[0] = '\0';
|
|
auto_reboot = FALSE;
|
|
xv_set(chooser,
|
|
FRAME_LABEL, "Disk Selector",
|
|
FILE_CHOOSER_DIRECTORY, dir,
|
|
FILE_CHOOSER_NOTIFY_FUNC, disk_change,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
static void eject_callback(void)
|
|
{
|
|
int diskno;
|
|
|
|
diskno = notice_prompt(panel, NULL,
|
|
NOTICE_MESSAGE_STRINGS,
|
|
"Eject Disk from drive?",
|
|
NULL,
|
|
NOTICE_BUTTON, "1", 1,
|
|
NOTICE_BUTTON, "2", 2,
|
|
NOTICE_BUTTON, "3", 3,
|
|
NOTICE_BUTTON, "4", 4,
|
|
NOTICE_BUTTON, "5", 5,
|
|
NOTICE_BUTTON, "6", 6,
|
|
NOTICE_BUTTON, "7", 7,
|
|
NOTICE_BUTTON, "8", 8,
|
|
NULL);
|
|
|
|
if (diskno >= 1 && diskno <= 8)
|
|
SIO_Dismount(diskno);
|
|
}
|
|
|
|
static void disable_callback(void)
|
|
{
|
|
int diskno;
|
|
|
|
diskno = notice_prompt(panel, NULL,
|
|
NOTICE_MESSAGE_STRINGS,
|
|
"Drive to Disable?",
|
|
NULL,
|
|
NOTICE_BUTTON, "1", 1,
|
|
NOTICE_BUTTON, "2", 2,
|
|
NOTICE_BUTTON, "3", 3,
|
|
NOTICE_BUTTON, "4", 4,
|
|
NOTICE_BUTTON, "5", 5,
|
|
NOTICE_BUTTON, "6", 6,
|
|
NOTICE_BUTTON, "7", 7,
|
|
NOTICE_BUTTON, "8", 8,
|
|
NULL);
|
|
|
|
if (diskno >= 1 && diskno <= 8)
|
|
SIO_DisableDrive(diskno);
|
|
}
|
|
|
|
static int rom_change(char *a, char *full_filename, char *filename)
|
|
{
|
|
return insert_rom(full_filename) ? XV_OK : XV_ERROR;
|
|
}
|
|
|
|
static void insert_rom_callback(void)
|
|
{
|
|
static char dir[FILENAME_MAX];
|
|
if (UI_n_atari_files_dir > 0)
|
|
strcpy(dir, UI_atari_files_dir[0]);
|
|
else
|
|
dir[0] = '\0';
|
|
xv_set(chooser,
|
|
FRAME_LABEL, "ROM Selector",
|
|
FILE_CHOOSER_DIRECTORY, dir,
|
|
FILE_CHOOSER_NOTIFY_FUNC, rom_change,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
static void remove_rom_callback(void)
|
|
{
|
|
CARTRIDGE_Remove();
|
|
Atari800_Coldstart();
|
|
}
|
|
|
|
static void exit_callback(void)
|
|
{
|
|
Atari800_Exit(FALSE);
|
|
exit(1);
|
|
}
|
|
|
|
static void option_callback(void)
|
|
{
|
|
menu_consol &= (~INPUT_CONSOL_OPTION);
|
|
}
|
|
|
|
static void select_callback(void)
|
|
{
|
|
menu_consol &= (~INPUT_CONSOL_SELECT);
|
|
}
|
|
|
|
static void start_callback(void)
|
|
{
|
|
menu_consol &= (~INPUT_CONSOL_START);
|
|
}
|
|
|
|
static void reset_callback(void)
|
|
{
|
|
Atari800_Warmstart();
|
|
}
|
|
|
|
static void coldstart_callback(void)
|
|
{
|
|
Atari800_Coldstart();
|
|
}
|
|
|
|
static void coldstart_sys(int machtype, int ram, const char *errmsg)
|
|
{
|
|
Atari800_machine_type = machtype;
|
|
MEMORY_ram_size = ram;
|
|
if (!Atari800_InitialiseMachine()) {
|
|
notice_prompt(panel, NULL,
|
|
NOTICE_MESSAGE_STRINGS,
|
|
errmsg,
|
|
NULL,
|
|
NOTICE_BUTTON, "Cancel", 1,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
static void coldstart_800_callback(void)
|
|
{
|
|
coldstart_sys(Atari800_MACHINE_800, 48, "Sorry, 800 ROM Unavailable");
|
|
}
|
|
|
|
static void coldstart_xl_callback(void)
|
|
{
|
|
coldstart_sys(Atari800_MACHINE_XLXE, 64, "Sorry, XL/XE ROM Unavailable");
|
|
}
|
|
|
|
static void coldstart_xe_callback(void)
|
|
{
|
|
coldstart_sys(Atari800_MACHINE_XLXE, 128, "Sorry, XL/XE ROM Unavailable");
|
|
}
|
|
|
|
static void coldstart_5200_callback(void)
|
|
{
|
|
coldstart_sys(Atari800_MACHINE_5200, 16, "Sorry, 5200 ROM Unavailable");
|
|
}
|
|
|
|
static void controllers_ok_callback(void)
|
|
{
|
|
xv_set(controllers_frame,
|
|
XV_SHOW, FALSE,
|
|
NULL);
|
|
}
|
|
|
|
static void controllers_callback(void)
|
|
{
|
|
xv_set(controllers_frame,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
static void sorry_message(void)
|
|
{
|
|
notice_prompt(panel, NULL,
|
|
NOTICE_MESSAGE_STRINGS,
|
|
"Sorry, controller already assigned",
|
|
"to another device",
|
|
NULL,
|
|
NOTICE_BUTTON, "Cancel", 1,
|
|
NULL);
|
|
}
|
|
|
|
static void keypad_callback(void)
|
|
{
|
|
int new_mode;
|
|
|
|
new_mode = xv_get(keypad_item, PANEL_VALUE);
|
|
|
|
if ((new_mode != xmouse_mode) &&
|
|
(new_mode != js0_mode) &&
|
|
(new_mode != js1_mode)) {
|
|
keypad_mode = new_mode;
|
|
}
|
|
else {
|
|
sorry_message();
|
|
xv_set(keypad_item,
|
|
PANEL_VALUE, keypad_mode,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
static void mouse_callback(void)
|
|
{
|
|
int new_mode;
|
|
|
|
new_mode = xv_get(mouse_item, PANEL_VALUE);
|
|
|
|
if ((new_mode != keypad_mode) &&
|
|
(new_mode != js0_mode) &&
|
|
(new_mode != js1_mode)) {
|
|
xmouse_mode = new_mode;
|
|
}
|
|
else {
|
|
sorry_message();
|
|
xv_set(mouse_item,
|
|
PANEL_VALUE, xmouse_mode,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
#ifdef LINUX_JOYSTICK
|
|
static void js0_callback(void)
|
|
{
|
|
int new_mode;
|
|
|
|
new_mode = xv_get(js0_item, PANEL_VALUE);
|
|
|
|
if ((new_mode != keypad_mode) &&
|
|
(new_mode != xmouse_mode) &&
|
|
(new_mode != js1_mode)) {
|
|
js0_mode = new_mode;
|
|
}
|
|
else {
|
|
sorry_message();
|
|
xv_set(js0_item,
|
|
PANEL_VALUE, js0_mode,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
static void js1_callback(void)
|
|
{
|
|
int new_mode;
|
|
|
|
new_mode = xv_get(js1_item, PANEL_VALUE);
|
|
|
|
if ((new_mode != keypad_mode) &&
|
|
(new_mode != xmouse_mode) &&
|
|
(new_mode != js0_mode)) {
|
|
js1_mode = new_mode;
|
|
}
|
|
else {
|
|
sorry_message();
|
|
xv_set(js1_item,
|
|
PANEL_VALUE, js1_mode,
|
|
NULL);
|
|
}
|
|
}
|
|
#endif /* LINUX_JOYSTICK */
|
|
|
|
static void performance_ok_callback(void)
|
|
{
|
|
xv_set(performance_frame,
|
|
XV_SHOW, FALSE,
|
|
NULL);
|
|
}
|
|
|
|
static void performance_callback(void)
|
|
{
|
|
xv_set(performance_frame,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
}
|
|
|
|
static void refresh_callback(Panel_item item, int value, Event * event)
|
|
{
|
|
Atari800_refresh_rate = value;
|
|
}
|
|
|
|
#endif /* XVIEW */
|
|
|
|
static void Atari_WhatIs(int mode)
|
|
{
|
|
switch (mode) {
|
|
case 0:
|
|
printf("Joystick 0");
|
|
break;
|
|
case 1:
|
|
printf("Joystick 1");
|
|
break;
|
|
case 2:
|
|
printf("Joystick 2");
|
|
break;
|
|
case 3:
|
|
printf("Joystick 3");
|
|
break;
|
|
default:
|
|
printf("not available");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef MOTIF
|
|
|
|
static void motif_boot_disk(Widget fs, XtPointer client_data,
|
|
XtPointer cbs)
|
|
{
|
|
char *filename;
|
|
|
|
if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
|
|
XmSTRING_DEFAULT_CHARSET, &filename)) {
|
|
if (*filename) {
|
|
SIO_Dismount(1);
|
|
if (SIO_Mount(1, filename, FALSE))
|
|
Atari800_Coldstart();
|
|
}
|
|
XtFree(filename);
|
|
}
|
|
XtUnmanageChild(fs);
|
|
XtPopdown(XtParent(fs));
|
|
}
|
|
|
|
static void motif_select_disk(Widget toggle, XtPointer client_data, XtPointer cbs)
|
|
{
|
|
motif_disk_sel = (int)(long) client_data;
|
|
}
|
|
|
|
static void motif_insert_disk(Widget fs, XtPointer client_data, XtPointer cbs)
|
|
{
|
|
char *filename;
|
|
|
|
if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
|
|
XmSTRING_DEFAULT_CHARSET, &filename)) {
|
|
if (*filename) {
|
|
SIO_Dismount(motif_disk_sel);
|
|
SIO_Mount(motif_disk_sel, filename, FALSE);
|
|
}
|
|
XtFree(filename);
|
|
}
|
|
XtUnmanageChild(fs);
|
|
XtPopdown(XtParent(fs));
|
|
}
|
|
|
|
static void motif_insert_rom(Widget fs, XtPointer client_data, XtPointer cbs)
|
|
{
|
|
char *filename;
|
|
|
|
if (XmStringGetLtoR(((XmFileSelectionBoxCallbackStruct *) cbs)->value,
|
|
XmSTRING_DEFAULT_CHARSET, &filename)) {
|
|
if (*filename) {
|
|
insert_rom(filename);
|
|
}
|
|
XtFree(filename);
|
|
}
|
|
XtUnmanageChild(fs);
|
|
XtPopdown(XtParent(fs));
|
|
}
|
|
|
|
static void motif_fs_cancel(Widget fs, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
XtUnmanageChild(fs);
|
|
XtPopdown(XtParent(fs));
|
|
}
|
|
|
|
static void motif_eject_cback(Widget button, XtPointer client_data, XtPointer cbs)
|
|
{
|
|
SIO_Dismount(((int)(long) client_data) + 1);
|
|
}
|
|
|
|
static void motif_disable_cback(Widget button, XtPointer client_data, XtPointer cbs)
|
|
{
|
|
SIO_DisableDrive(((int)(long) client_data) + 1);
|
|
}
|
|
|
|
static void update_fsel(Widget fsel)
|
|
{
|
|
XmString dirmask;
|
|
|
|
XtVaGetValues(fsel, XmNdirMask, &dirmask, NULL);
|
|
XmFileSelectionDoSearch(fsel, dirmask);
|
|
}
|
|
|
|
static void motif_system_cback(Widget w, XtPointer item_no, XtPointer cbs)
|
|
{
|
|
XmString t;
|
|
int status;
|
|
char *errmsg = NULL;
|
|
|
|
switch ((int)(long) item_no) {
|
|
case 0:
|
|
update_fsel(fsel_b);
|
|
XtManageChild(fsel_b);
|
|
XtPopup(XtParent(fsel_b), XtGrabNone);
|
|
break;
|
|
case 1:
|
|
/* insert disk */
|
|
update_fsel(fsel_d);
|
|
XtManageChild(fsel_d);
|
|
XtPopup(XtParent(fsel_d), XtGrabNone);
|
|
break;
|
|
case 2:
|
|
/* eject disk */
|
|
/* handled by pullright menu */
|
|
break;
|
|
case 3:
|
|
/* disable drive */
|
|
/* handled by pullright menu */
|
|
break;
|
|
case 4:
|
|
/* insert rom */
|
|
update_fsel(fsel_r);
|
|
XtManageChild(fsel_r);
|
|
XtPopup(XtParent(fsel_r), XtGrabNone);
|
|
break;
|
|
case 5:
|
|
CARTRIDGE_Remove();
|
|
Atari800_Coldstart();
|
|
break;
|
|
case 6:
|
|
Atari800_machine_type = Atari800_MACHINE_800;
|
|
MEMORY_ram_size = 48;
|
|
status = Atari800_InitialiseMachine();
|
|
if (status == 0)
|
|
errmsg = "Sorry, 800 ROM Unavailable";
|
|
break;
|
|
case 7:
|
|
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
|
MEMORY_ram_size = 64;
|
|
status = Atari800_InitialiseMachine();
|
|
if (status == 0)
|
|
errmsg = "Sorry, XL/XE ROM Unavailable";
|
|
break;
|
|
case 8:
|
|
Atari800_machine_type = Atari800_MACHINE_XLXE;
|
|
MEMORY_ram_size = 128;
|
|
status = Atari800_InitialiseMachine();
|
|
if (status == 0)
|
|
errmsg = "Sorry, XL/XE ROM Unavailable";
|
|
break;
|
|
case 9:
|
|
Atari800_machine_type = Atari800_MACHINE_5200;
|
|
MEMORY_ram_size = 16;
|
|
status = Atari800_InitialiseMachine();
|
|
if (status == 0)
|
|
errmsg = "Sorry, 5200 ROM Unavailable";
|
|
break;
|
|
case 10:
|
|
Atari800_Exit(FALSE);
|
|
exit(0);
|
|
}
|
|
|
|
if (errmsg) {
|
|
static Widget dialog = NULL;
|
|
|
|
if (!dialog) {
|
|
Arg arg[1];
|
|
|
|
dialog = XmCreateErrorDialog(main_w, "message", arg, 0);
|
|
|
|
XtVaSetValues(dialog,
|
|
XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
|
|
NULL);
|
|
|
|
XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON));
|
|
XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
|
|
}
|
|
t = XmStringCreateSimple(errmsg);
|
|
XtVaSetValues(dialog,
|
|
XmNmessageString, t,
|
|
NULL);
|
|
XmStringFree(t);
|
|
XtManageChild(dialog);
|
|
}
|
|
}
|
|
|
|
static void motif_consol_cback(Widget w, XtPointer item_no, XtPointer cbs)
|
|
{
|
|
switch ((int)(long) item_no) {
|
|
case 0:
|
|
menu_consol &= (~INPUT_CONSOL_OPTION);
|
|
break;
|
|
case 1:
|
|
menu_consol &= (~INPUT_CONSOL_SELECT);
|
|
break;
|
|
case 2:
|
|
menu_consol &= (~INPUT_CONSOL_START);
|
|
break;
|
|
case 3:
|
|
Atari800_Warmstart();
|
|
break;
|
|
case 4:
|
|
Atari800_Coldstart();
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void motif_keypress(Widget w, XtPointer client_data, XEvent *event,
|
|
Boolean *continue_to_dispatch)
|
|
{
|
|
xview_keycode = GetKeyCode(event);
|
|
}
|
|
|
|
static void motif_exposure(Widget w, XtPointer client_data, XEvent *event,
|
|
Boolean *continue_to_dispatch)
|
|
{
|
|
modified = TRUE;
|
|
}
|
|
|
|
#endif /* MOTIF */
|
|
|
|
int PLATFORM_Initialise(int *argc, char *argv[])
|
|
{
|
|
#if !defined(XVIEW) && !defined(MOTIF)
|
|
XSetWindowAttributes xswda;
|
|
#endif
|
|
|
|
int depth;
|
|
int i, j;
|
|
int mode = 0;
|
|
int help_only = FALSE;
|
|
|
|
#ifdef XVIEW
|
|
int ypos;
|
|
|
|
xv_init(XV_INIT_ARGC_PTR_ARGV, argc, argv, NULL);
|
|
#endif
|
|
|
|
#ifdef MOTIF
|
|
toplevel = XtVaAppInitialize(&app, "Atari800",
|
|
NULL, 0,
|
|
argc, argv, NULL,
|
|
XtNtitle, Atari800_TITLE,
|
|
NULL);
|
|
#endif
|
|
|
|
for (i = j = 1; i < *argc; i++) {
|
|
int i_a = (i + 1 < *argc); /* is argument available? */
|
|
int a_m = FALSE; /* error, argument missing! */
|
|
|
|
if (strcmp(argv[i], "-small") == 0)
|
|
windowsize = Small;
|
|
else if (strcmp(argv[i], "-large") == 0)
|
|
windowsize = Large;
|
|
else if (strcmp(argv[i], "-huge") == 0)
|
|
windowsize = Huge;
|
|
else if (strcmp(argv[i], "-clip_x") == 0)
|
|
if (i_a)
|
|
clipping_x = atoi(argv[++i]);
|
|
else a_m = TRUE;
|
|
else if (strcmp(argv[i], "-clip_y") == 0)
|
|
if (i_a)
|
|
clipping_y = atoi(argv[++i]);
|
|
else a_m = TRUE;
|
|
else if (strcmp(argv[i], "-clip_width") == 0)
|
|
if (i_a)
|
|
clipping_width = atoi(argv[++i]);
|
|
else a_m = TRUE;
|
|
else if (strcmp(argv[i], "-clip_height") == 0)
|
|
if (i_a)
|
|
clipping_height = atoi(argv[++i]);
|
|
else a_m = TRUE;
|
|
else if (strcmp(argv[i], "-x11bug") == 0)
|
|
x11bug = TRUE;
|
|
else if (strcmp(argv[i], "-sio") == 0)
|
|
x11_monitor = MONITOR_SIO;
|
|
else if (strcmp(argv[i], "-private_cmap") == 0)
|
|
private_cmap = TRUE;
|
|
else if (strcmp(argv[i], "-keypad") == 0) {
|
|
if (keypad_mode == -1)
|
|
keypad_mode = mode++;
|
|
}
|
|
else {
|
|
if (strcmp(argv[i], "-help") == 0 || a_m) {
|
|
help_only = TRUE;
|
|
printf("\t-small Small window (%dx%d)\n",
|
|
clipping_width, clipping_height);
|
|
printf("\t-large Large window (%dx%d)\n",
|
|
clipping_width * 2, clipping_height * 2);
|
|
printf("\t-huge Huge window (%dx%d)\n",
|
|
clipping_width * 3, clipping_height * 3);
|
|
printf("\t-x11bug Enable debug code in atari_x11.c\n");
|
|
printf("\t-clip_x <n> Set left offset in pixels for clipping\n");
|
|
printf("\t-clip_width <n> Set window clip-width\n");
|
|
printf("\t-clip_y <n> Set top offset for clipping\n");
|
|
printf("\t-clip_height <n> Set window clip-height\n");
|
|
printf("\t-private_cmap Use private colormap\n");
|
|
printf("\t-sio Show SIO monitor\n");
|
|
printf("\t-keypad Keypad mode\n");
|
|
break;
|
|
}
|
|
argv[j++] = argv[i];
|
|
}
|
|
}
|
|
|
|
if (help_only)
|
|
return TRUE;
|
|
|
|
*argc = j;
|
|
|
|
#ifdef SOUND
|
|
if (!Sound_Initialise(argc, argv))
|
|
return FALSE;
|
|
#endif
|
|
|
|
if ((clipping_x < 0) || (clipping_x >= Screen_WIDTH))
|
|
clipping_x = 0;
|
|
if ((clipping_y < 0) || (clipping_y >= Screen_HEIGHT))
|
|
clipping_y = 0;
|
|
if ((clipping_width <= 0) || (clipping_x + clipping_width > Screen_WIDTH))
|
|
clipping_width = Screen_WIDTH - clipping_x;
|
|
if ((clipping_height <= 0) || (clipping_y + clipping_height > Screen_HEIGHT))
|
|
clipping_height = Screen_HEIGHT - clipping_y;
|
|
Screen_visible_x1 = clipping_x;
|
|
Screen_visible_x2 = clipping_x + clipping_width;
|
|
Screen_visible_y1 = clipping_y;
|
|
Screen_visible_y2 = clipping_y + clipping_height;
|
|
switch (windowsize) {
|
|
case Small:
|
|
clipping_factor = 1;
|
|
window_width = clipping_width;
|
|
window_height = clipping_height;
|
|
break;
|
|
case Large:
|
|
clipping_factor = 2;
|
|
window_width = clipping_width * 2;
|
|
window_height = clipping_height * 2;
|
|
break;
|
|
case Huge:
|
|
clipping_factor = 3;
|
|
window_width = clipping_width * 3;
|
|
window_height = clipping_height * 3;
|
|
break;
|
|
}
|
|
|
|
#ifdef LINUX_JOYSTICK
|
|
js0 = open("/dev/js0", O_RDONLY, 0777);
|
|
if (js0 != -1) {
|
|
int status;
|
|
|
|
status = read(js0, &js_data, JS_RETURN);
|
|
if (status != JS_RETURN) {
|
|
perror("/dev/js0");
|
|
exit(1);
|
|
}
|
|
js0_centre_x = js_data.x;
|
|
js0_centre_y = js_data.y;
|
|
|
|
if (x11bug)
|
|
printf("Joystick 0: centre_x = %d, centry_y = %d\n",
|
|
js0_centre_x, js0_centre_y);
|
|
|
|
js0_mode = mode++;
|
|
}
|
|
js1 = open("/dev/js1", O_RDONLY, 0777);
|
|
if (js1 != -1) {
|
|
int status;
|
|
|
|
status = read(js1, &js_data, JS_RETURN);
|
|
if (status != JS_RETURN) {
|
|
perror("/dev/js1");
|
|
exit(1);
|
|
}
|
|
js1_centre_x = js_data.x;
|
|
js1_centre_y = js_data.y;
|
|
|
|
if (x11bug)
|
|
printf("Joystick 1: centre_x = %d, centry_y = %d\n",
|
|
js1_centre_x, js1_centre_y);
|
|
|
|
js1_mode = mode++;
|
|
}
|
|
#endif
|
|
|
|
xmouse_mode = mode++;
|
|
if (keypad_mode == -1)
|
|
keypad_mode = mode++;
|
|
|
|
#ifdef XVIEW
|
|
frame = (Frame) xv_create((Xv_opaque) NULL, FRAME,
|
|
FRAME_LABEL, Atari800_TITLE,
|
|
FRAME_SHOW_RESIZE_CORNER, FALSE,
|
|
XV_WIDTH, window_width,
|
|
XV_HEIGHT, window_height + 27,
|
|
FRAME_SHOW_FOOTER, TRUE,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
|
|
panel = (Panel) xv_create(frame, PANEL,
|
|
XV_HEIGHT, 25,
|
|
XV_SHOW, TRUE,
|
|
NULL);
|
|
|
|
system_menu = xv_create((Xv_opaque) NULL, MENU,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Boot Disk",
|
|
MENU_NOTIFY_PROC, boot_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Insert Disk",
|
|
MENU_NOTIFY_PROC, insert_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Eject Disk",
|
|
MENU_NOTIFY_PROC, eject_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Disable Drive",
|
|
MENU_NOTIFY_PROC, disable_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Insert Cartridge",
|
|
MENU_NOTIFY_PROC, insert_rom_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Remove Cartridge",
|
|
MENU_NOTIFY_PROC, remove_rom_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Atari 800",
|
|
MENU_NOTIFY_PROC, coldstart_800_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Atari 800XL",
|
|
MENU_NOTIFY_PROC, coldstart_xl_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Atari 130XE",
|
|
MENU_NOTIFY_PROC, coldstart_xe_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Atari 5200",
|
|
MENU_NOTIFY_PROC, coldstart_5200_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Exit",
|
|
MENU_NOTIFY_PROC, exit_callback,
|
|
NULL,
|
|
NULL);
|
|
|
|
xv_create(panel, PANEL_BUTTON,
|
|
PANEL_LABEL_STRING, "System",
|
|
PANEL_ITEM_MENU, system_menu,
|
|
NULL);
|
|
|
|
consol_menu = (Menu) xv_create((Xv_opaque) NULL, MENU,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Option",
|
|
MENU_NOTIFY_PROC, option_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Select",
|
|
MENU_NOTIFY_PROC, select_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Start",
|
|
MENU_NOTIFY_PROC, start_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Reset",
|
|
MENU_NOTIFY_PROC, reset_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Coldstart",
|
|
MENU_NOTIFY_PROC, coldstart_callback,
|
|
NULL,
|
|
NULL);
|
|
|
|
xv_create(panel, PANEL_BUTTON,
|
|
PANEL_LABEL_STRING, "Console",
|
|
PANEL_ITEM_MENU, consol_menu,
|
|
NULL);
|
|
|
|
options_menu = (Menu) xv_create((Xv_opaque) NULL, MENU,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Controllers",
|
|
MENU_NOTIFY_PROC, controllers_callback,
|
|
NULL,
|
|
MENU_ITEM,
|
|
MENU_STRING, "Performance",
|
|
MENU_NOTIFY_PROC, performance_callback,
|
|
NULL,
|
|
NULL);
|
|
|
|
xv_create(panel, PANEL_BUTTON,
|
|
PANEL_LABEL_STRING, "Options",
|
|
PANEL_ITEM_MENU, options_menu,
|
|
NULL);
|
|
|
|
canvas = (Canvas) xv_create(frame, CANVAS,
|
|
CANVAS_WIDTH, window_width,
|
|
CANVAS_HEIGHT, window_height,
|
|
NULL);
|
|
/*
|
|
=====================================
|
|
Create Controller Configuration Frame
|
|
=====================================
|
|
*/
|
|
controllers_frame = (Frame) xv_create(frame, FRAME_CMD,
|
|
FRAME_LABEL, "Controller Configuration",
|
|
XV_WIDTH, 300,
|
|
XV_HEIGHT, 150,
|
|
NULL);
|
|
|
|
controllers_panel = (Panel) xv_get(controllers_frame, FRAME_CMD_PANEL,
|
|
NULL);
|
|
|
|
ypos = 10;
|
|
keypad_item = (Panel_item) xv_create(controllers_panel, PANEL_CHOICE_STACK,
|
|
PANEL_VALUE_X, 150,
|
|
PANEL_VALUE_Y, ypos,
|
|
PANEL_LAYOUT, PANEL_HORIZONTAL,
|
|
PANEL_LABEL_STRING, "Numeric Keypad",
|
|
PANEL_CHOICE_STRINGS,
|
|
"Joystick 1",
|
|
"Joystick 2",
|
|
"Joystick 3",
|
|
"Joystick 4",
|
|
NULL,
|
|
PANEL_VALUE, keypad_mode,
|
|
PANEL_NOTIFY_PROC, keypad_callback,
|
|
NULL);
|
|
ypos += 25;
|
|
|
|
mouse_item = (Panel_item) xv_create(controllers_panel, PANEL_CHOICE_STACK,
|
|
PANEL_VALUE_X, 150,
|
|
PANEL_VALUE_Y, ypos,
|
|
PANEL_LAYOUT, PANEL_HORIZONTAL,
|
|
PANEL_LABEL_STRING, "Mouse",
|
|
PANEL_CHOICE_STRINGS,
|
|
"Joystick 1",
|
|
"Joystick 2",
|
|
"Joystick 3",
|
|
"Joystick 4",
|
|
NULL,
|
|
PANEL_VALUE, xmouse_mode,
|
|
PANEL_NOTIFY_PROC, mouse_callback,
|
|
NULL);
|
|
ypos += 25;
|
|
|
|
#ifdef LINUX_JOYSTICK
|
|
if (js0 != -1) {
|
|
js0_item = (Panel_item) xv_create(controllers_panel, PANEL_CHOICE_STACK,
|
|
PANEL_VALUE_X, 150,
|
|
PANEL_VALUE_Y, ypos,
|
|
PANEL_LAYOUT, PANEL_HORIZONTAL,
|
|
PANEL_LABEL_STRING, "/dev/js0",
|
|
PANEL_CHOICE_STRINGS,
|
|
"Joystick 1",
|
|
"Joystick 2",
|
|
"Joystick 3",
|
|
"Joystick 4",
|
|
NULL,
|
|
PANEL_VALUE, js0_mode,
|
|
PANEL_NOTIFY_PROC, js0_callback,
|
|
NULL);
|
|
ypos += 25;
|
|
}
|
|
if (js1 != -1) {
|
|
js1_item = (Panel_item) xv_create(controllers_panel, PANEL_CHOICE_STACK,
|
|
PANEL_VALUE_X, 150,
|
|
PANEL_VALUE_Y, ypos,
|
|
PANEL_LAYOUT, PANEL_HORIZONTAL,
|
|
PANEL_LABEL_STRING, "/dev/js1",
|
|
PANEL_CHOICE_STRINGS,
|
|
"Joystick 1",
|
|
"Joystick 2",
|
|
"Joystick 3",
|
|
"Joystick 4",
|
|
NULL,
|
|
PANEL_VALUE, js1_mode,
|
|
PANEL_NOTIFY_PROC, js1_callback,
|
|
NULL);
|
|
ypos += 25;
|
|
}
|
|
#endif
|
|
|
|
xv_create(controllers_panel, PANEL_BUTTON,
|
|
XV_X, 130,
|
|
XV_Y, 125,
|
|
PANEL_LABEL_STRING, "OK",
|
|
PANEL_NOTIFY_PROC, controllers_ok_callback,
|
|
NULL);
|
|
/*
|
|
======================================
|
|
Create Performance Configuration Frame
|
|
======================================
|
|
*/
|
|
performance_frame = (Frame) xv_create(frame, FRAME_CMD,
|
|
FRAME_LABEL, "Performance Configuration",
|
|
XV_WIDTH, 400,
|
|
XV_HEIGHT, 100,
|
|
NULL);
|
|
|
|
performance_panel = (Panel) xv_get(performance_frame, FRAME_CMD_PANEL,
|
|
NULL);
|
|
|
|
ypos = 10;
|
|
refresh_slider = (Panel_item) xv_create(performance_panel, PANEL_SLIDER,
|
|
PANEL_VALUE_X, 155,
|
|
PANEL_VALUE_Y, ypos,
|
|
PANEL_LAYOUT, PANEL_HORIZONTAL,
|
|
PANEL_LABEL_STRING, "Screen Refresh Rate",
|
|
PANEL_VALUE, Atari800_refresh_rate,
|
|
PANEL_MIN_VALUE, 1,
|
|
PANEL_MAX_VALUE, 32,
|
|
PANEL_SLIDER_WIDTH, 100,
|
|
PANEL_TICKS, 32,
|
|
PANEL_NOTIFY_PROC, refresh_callback,
|
|
NULL);
|
|
ypos += 25;
|
|
|
|
xv_create(performance_panel, PANEL_BUTTON,
|
|
XV_X, 180,
|
|
XV_Y, 75,
|
|
PANEL_LABEL_STRING, "OK",
|
|
PANEL_NOTIFY_PROC, performance_ok_callback,
|
|
NULL);
|
|
/*
|
|
====================
|
|
Get X Window Objects
|
|
====================
|
|
*/
|
|
display = (Display *) xv_get(frame, XV_DISPLAY);
|
|
if (!display) {
|
|
printf("Failed to open display\n");
|
|
exit(1);
|
|
}
|
|
autorepeat_get();
|
|
screen = XDefaultScreenOfDisplay(display);
|
|
if (!screen) {
|
|
printf("Unable to get screen\n");
|
|
exit(1);
|
|
}
|
|
visual = XDefaultVisualOfScreen(screen);
|
|
if (!visual) {
|
|
printf("Unable to get visual\n");
|
|
exit(1);
|
|
}
|
|
window = (Window) xv_get(canvas_paint_window(canvas), XV_XID);
|
|
depth = XDefaultDepthOfScreen(screen);
|
|
cmap = XDefaultColormapOfScreen(screen);
|
|
|
|
chooser = (Frame) xv_create(frame, FILE_CHOOSER,
|
|
FILE_CHOOSER_TYPE, FILE_CHOOSER_OPEN,
|
|
NULL);
|
|
|
|
xv_set(canvas_paint_window(canvas),
|
|
WIN_EVENT_PROC, event_proc,
|
|
WIN_CONSUME_EVENTS, WIN_ASCII_EVENTS, WIN_MOUSE_BUTTONS,
|
|
WIN_VISIBILITY_NOTIFY, /* mmm */
|
|
NULL,
|
|
NULL);
|
|
|
|
#endif /* XVIEW */
|
|
|
|
#ifdef MOTIF
|
|
{
|
|
Widget menubar;
|
|
|
|
XmString s_system;
|
|
XmString s_boot_disk;
|
|
XmString s_insert_disk;
|
|
XmString s_eject_disk;
|
|
XmString s_disable_drive;
|
|
XmString s_insert_cart;
|
|
XmString s_remove_cart;
|
|
XmString s_os800;
|
|
XmString s_osxl;
|
|
XmString s_osxe;
|
|
XmString s_os5200;
|
|
XmString s_exit;
|
|
|
|
XmString s_console;
|
|
XmString s_option;
|
|
XmString s_select;
|
|
XmString s_start;
|
|
XmString s_warmstart;
|
|
XmString s_coldstart;
|
|
|
|
XmString s_label;
|
|
|
|
XmString s_d1, s_d2, s_d3, s_d4;
|
|
XmString s_d5, s_d6, s_d7, s_d8;
|
|
|
|
char *tmpstr;
|
|
XmString xmtmpstr;
|
|
|
|
Arg args[8];
|
|
int n;
|
|
|
|
main_w = XtVaCreateManagedWidget("main_window",
|
|
xmMainWindowWidgetClass, toplevel,
|
|
NULL);
|
|
|
|
s_system = XmStringCreateSimple("System");
|
|
s_boot_disk = XmStringCreateSimple("Boot Disk...");
|
|
s_insert_disk = XmStringCreateSimple("Insert Disk...");
|
|
s_eject_disk = XmStringCreateSimple("Eject Disk");
|
|
s_disable_drive = XmStringCreateSimple("Disable Drive");
|
|
s_insert_cart = XmStringCreateSimple("Insert Cartridge...");
|
|
s_remove_cart = XmStringCreateSimple("Remove Cartridge");
|
|
s_os800 = XmStringCreateSimple("Atari 800");
|
|
s_osxl = XmStringCreateSimple("Atari 800XL");
|
|
s_osxe = XmStringCreateSimple("Atari 130XE");
|
|
s_os5200 = XmStringCreateSimple("Atari 5200");
|
|
s_exit = XmStringCreateSimple("Exit");
|
|
|
|
s_console = XmStringCreateSimple("Console");
|
|
s_option = XmStringCreateSimple("Option");
|
|
s_select = XmStringCreateSimple("Select");
|
|
s_start = XmStringCreateSimple("Start");
|
|
s_warmstart = XmStringCreateSimple("Warmstart");
|
|
s_coldstart = XmStringCreateSimple("Coldstart");
|
|
|
|
menubar = XmVaCreateSimpleMenuBar(main_w, "menubar",
|
|
XmVaCASCADEBUTTON, s_system, 'S',
|
|
XmVaCASCADEBUTTON, s_console, 'C',
|
|
NULL);
|
|
|
|
system_menu =
|
|
XmVaCreateSimplePulldownMenu(menubar, "system_menu", 0, motif_system_cback,
|
|
XmVaPUSHBUTTON, s_boot_disk, 'o', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_insert_disk, 'I', NULL, NULL,
|
|
XmVaCASCADEBUTTON, s_eject_disk, 'j',
|
|
XmVaCASCADEBUTTON, s_disable_drive, 'D',
|
|
XmVaSEPARATOR,
|
|
XmVaPUSHBUTTON, s_insert_cart, 'n', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_remove_cart, 'R', NULL, NULL,
|
|
XmVaSEPARATOR,
|
|
XmVaPUSHBUTTON, s_os800, '8', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_osxl, 'L', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_osxe, 'E', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_os5200, '5', NULL, NULL,
|
|
XmVaSEPARATOR,
|
|
XmVaPUSHBUTTON, s_exit, 'x', NULL, NULL,
|
|
NULL);
|
|
|
|
XmVaCreateSimplePulldownMenu(menubar, "console_menu", 1, motif_consol_cback,
|
|
XmVaPUSHBUTTON, s_option, 'O', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_select, 't', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_start, 'S', NULL, NULL,
|
|
XmVaSEPARATOR,
|
|
XmVaPUSHBUTTON, s_warmstart, 'W', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_coldstart, 'C', NULL, NULL,
|
|
NULL);
|
|
|
|
XmStringFree(s_system);
|
|
XmStringFree(s_boot_disk);
|
|
XmStringFree(s_insert_disk);
|
|
XmStringFree(s_eject_disk);
|
|
XmStringFree(s_disable_drive);
|
|
XmStringFree(s_insert_cart);
|
|
XmStringFree(s_remove_cart);
|
|
XmStringFree(s_os800);
|
|
XmStringFree(s_osxl);
|
|
XmStringFree(s_osxe);
|
|
XmStringFree(s_os5200);
|
|
XmStringFree(s_exit);
|
|
|
|
XmStringFree(s_console);
|
|
XmStringFree(s_option);
|
|
XmStringFree(s_select);
|
|
XmStringFree(s_start);
|
|
XmStringFree(s_warmstart);
|
|
XmStringFree(s_coldstart);
|
|
|
|
XtManageChild(menubar);
|
|
|
|
fsel_b = XmCreateFileSelectionDialog(toplevel, "boot_disk", NULL, 0);
|
|
XtAddCallback(fsel_b, XmNokCallback, motif_boot_disk, NULL);
|
|
XtAddCallback(fsel_b, XmNcancelCallback, motif_fs_cancel, NULL);
|
|
|
|
fsel_d = XmCreateFileSelectionDialog(toplevel, "load_disk", NULL, 0);
|
|
XtAddCallback(fsel_d, XmNokCallback, motif_insert_disk, NULL);
|
|
XtAddCallback(fsel_d, XmNcancelCallback, motif_fs_cancel, NULL);
|
|
|
|
n = 0;
|
|
XtSetArg(args[n], XmNradioBehavior, True);
|
|
n++;
|
|
XtSetArg(args[n], XmNradioAlwaysOne, True);
|
|
n++;
|
|
XtSetArg(args[n], XmNorientation, XmHORIZONTAL);
|
|
n++;
|
|
rbox_d = XmCreateWorkArea(fsel_d, "rbox_d", args, n);
|
|
XtManageChild(rbox_d);
|
|
|
|
s_label = XmStringCreateSimple("D1:");
|
|
n = 0;
|
|
XtSetArg(args[n], XmNlabelString, s_label);
|
|
n++;
|
|
XtSetArg(args[n], XmNset, True);
|
|
n++;
|
|
togg_d1 = XmCreateToggleButtonGadget(rbox_d, "togg_d1", args, n);
|
|
XtManageChild(togg_d1);
|
|
XmStringFree(s_label);
|
|
XtAddCallback(togg_d1, XmNarmCallback, motif_select_disk, (XtPointer) 1);
|
|
|
|
s_label = XmStringCreateSimple("D2:");
|
|
n = 0;
|
|
XtSetArg(args[n], XmNlabelString, s_label);
|
|
n++;
|
|
togg_d2 = XmCreateToggleButtonGadget(rbox_d, "togg_d2", args, n);
|
|
XtManageChild(togg_d2);
|
|
XmStringFree(s_label);
|
|
XtAddCallback(togg_d2, XmNarmCallback, motif_select_disk, (XtPointer) 2);
|
|
|
|
s_label = XmStringCreateSimple("D3:");
|
|
n = 0;
|
|
XtSetArg(args[n], XmNlabelString, s_label);
|
|
n++;
|
|
togg_d3 = XmCreateToggleButtonGadget(rbox_d, "togg_d3", args, n);
|
|
XtManageChild(togg_d3);
|
|
XmStringFree(s_label);
|
|
XtAddCallback(togg_d3, XmNarmCallback, motif_select_disk, (XtPointer) 3);
|
|
|
|
s_label = XmStringCreateSimple("D4:");
|
|
n = 0;
|
|
XtSetArg(args[n], XmNlabelString, s_label);
|
|
n++;
|
|
togg_d4 = XmCreateToggleButtonGadget(rbox_d, "togg_d4", args, n);
|
|
XtManageChild(togg_d4);
|
|
XmStringFree(s_label);
|
|
XtAddCallback(togg_d4, XmNarmCallback, motif_select_disk, (XtPointer) 4);
|
|
|
|
s_label = XmStringCreateSimple("D5:");
|
|
n = 0;
|
|
XtSetArg(args[n], XmNlabelString, s_label);
|
|
n++;
|
|
togg_d5 = XmCreateToggleButtonGadget(rbox_d, "togg_d5", args, n);
|
|
XtManageChild(togg_d5);
|
|
XmStringFree(s_label);
|
|
XtAddCallback(togg_d5, XmNarmCallback, motif_select_disk, (XtPointer) 5);
|
|
|
|
s_label = XmStringCreateSimple("D6:");
|
|
n = 0;
|
|
XtSetArg(args[n], XmNlabelString, s_label);
|
|
n++;
|
|
togg_d6 = XmCreateToggleButtonGadget(rbox_d, "togg_d6", args, n);
|
|
XtManageChild(togg_d6);
|
|
XmStringFree(s_label);
|
|
XtAddCallback(togg_d6, XmNarmCallback, motif_select_disk, (XtPointer) 6);
|
|
|
|
s_label = XmStringCreateSimple("D7:");
|
|
n = 0;
|
|
XtSetArg(args[n], XmNlabelString, s_label);
|
|
n++;
|
|
togg_d7 = XmCreateToggleButtonGadget(rbox_d, "togg_d7", args, n);
|
|
XtManageChild(togg_d7);
|
|
XmStringFree(s_label);
|
|
XtAddCallback(togg_d7, XmNarmCallback, motif_select_disk, (XtPointer) 7);
|
|
|
|
s_label = XmStringCreateSimple("D8:");
|
|
n = 0;
|
|
XtSetArg(args[n], XmNlabelString, s_label);
|
|
n++;
|
|
togg_d8 = XmCreateToggleButtonGadget(rbox_d, "togg_d8", args, n);
|
|
XtManageChild(togg_d8);
|
|
XmStringFree(s_label);
|
|
XtAddCallback(togg_d8, XmNarmCallback, motif_select_disk, (XtPointer) 8);
|
|
|
|
|
|
fsel_r = XmCreateFileSelectionDialog(toplevel, "load_rom", NULL, 0);
|
|
XtAddCallback(fsel_r, XmNokCallback, motif_insert_rom, NULL);
|
|
XtAddCallback(fsel_r, XmNcancelCallback, motif_fs_cancel, NULL);
|
|
|
|
if (UI_n_atari_files_dir > 0) {
|
|
tmpstr = (char *) XtMalloc(strlen(UI_atari_files_dir[0] + 3));
|
|
strcpy(Util_stpcpy(tmpstr, UI_atari_files_dir[0]), "/*");
|
|
}
|
|
else {
|
|
tmpstr = (char *) XtMalloc(4);
|
|
strcpy(tmpstr, "./*");
|
|
}
|
|
xmtmpstr = XmStringCreateSimple(tmpstr);
|
|
XmFileSelectionDoSearch(fsel_b, xmtmpstr);
|
|
XmFileSelectionDoSearch(fsel_d, xmtmpstr);
|
|
XmStringFree(xmtmpstr);
|
|
/* XXX: can use the same tmpstr? can use the same xmtmpstr? */
|
|
xmtmpstr = XmStringCreateSimple(tmpstr);
|
|
XmFileSelectionDoSearch(fsel_r, xmtmpstr);
|
|
XmStringFree(xmtmpstr);
|
|
XtFree(tmpstr);
|
|
|
|
s_d1 = XmStringCreateSimple("D1:");
|
|
s_d2 = XmStringCreateSimple("D2:");
|
|
s_d3 = XmStringCreateSimple("D3:");
|
|
s_d4 = XmStringCreateSimple("D4:");
|
|
s_d5 = XmStringCreateSimple("D5:");
|
|
s_d6 = XmStringCreateSimple("D6:");
|
|
s_d7 = XmStringCreateSimple("D7:");
|
|
s_d8 = XmStringCreateSimple("D8:");
|
|
eject_menu = XmVaCreateSimplePulldownMenu(system_menu,
|
|
"eject_disk", 2,
|
|
motif_eject_cback,
|
|
XmVaPUSHBUTTON, s_d1, '1', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d2, '2', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d3, '3', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d4, '4', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d5, '5', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d6, '6', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d7, '7', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d8, '8', NULL, NULL,
|
|
NULL);
|
|
disable_menu = XmVaCreateSimplePulldownMenu(system_menu,
|
|
"disable_disk", 3,
|
|
motif_disable_cback,
|
|
XmVaPUSHBUTTON, s_d1, '1', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d2, '2', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d3, '3', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d4, '4', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d5, '5', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d6, '6', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d7, '7', NULL, NULL,
|
|
XmVaPUSHBUTTON, s_d8, '8', NULL, NULL,
|
|
NULL);
|
|
XmStringFree(s_d1);
|
|
XmStringFree(s_d2);
|
|
XmStringFree(s_d3);
|
|
XmStringFree(s_d4);
|
|
XmStringFree(s_d5);
|
|
XmStringFree(s_d6);
|
|
XmStringFree(s_d7);
|
|
XmStringFree(s_d8);
|
|
|
|
drawing_area = XtVaCreateManagedWidget("Canvas",
|
|
xmDrawingAreaWidgetClass, main_w,
|
|
XmNunitType, XmPIXELS,
|
|
XmNheight, window_height,
|
|
XmNwidth, window_width,
|
|
XmNresizePolicy, XmNONE,
|
|
NULL);
|
|
|
|
XtAddEventHandler(drawing_area,
|
|
KeyPressMask | KeyReleaseMask | VisibilityChangeMask | FocusChangeMask, /* mmm */
|
|
False,
|
|
motif_keypress, NULL);
|
|
|
|
XtAddEventHandler(drawing_area,
|
|
ExposureMask,
|
|
False,
|
|
motif_exposure, NULL);
|
|
|
|
XtRealizeWidget(toplevel);
|
|
}
|
|
|
|
display = XtDisplay(drawing_area);
|
|
|
|
window = XtWindow(drawing_area);
|
|
|
|
screen = XDefaultScreenOfDisplay(display);
|
|
if (!screen) {
|
|
printf("Unable to get screen\n");
|
|
exit(1);
|
|
}
|
|
visual = XDefaultVisualOfScreen(screen);
|
|
if (!visual) {
|
|
printf("Unable to get visual\n");
|
|
exit(1);
|
|
}
|
|
depth = XDefaultDepthOfScreen(screen);
|
|
cmap = XDefaultColormapOfScreen(screen);
|
|
#endif /* MOTIF */
|
|
|
|
#if !defined(XVIEW) && !defined(MOTIF)
|
|
display = XOpenDisplay(NULL);
|
|
if (!display) {
|
|
printf("Failed to open display\n");
|
|
exit(1);
|
|
}
|
|
screen = XDefaultScreenOfDisplay(display);
|
|
if (!screen) {
|
|
printf("Unable to get screen\n");
|
|
exit(1);
|
|
}
|
|
visual = XDefaultVisualOfScreen(screen);
|
|
if (!visual) {
|
|
printf("Unable to get visual\n");
|
|
exit(1);
|
|
}
|
|
depth = XDefaultDepthOfScreen(screen);
|
|
|
|
if (private_cmap)
|
|
cmap = XCreateColormap(display,
|
|
XRootWindowOfScreen(screen),
|
|
visual,
|
|
AllocNone);
|
|
else
|
|
cmap = XDefaultColormapOfScreen(screen);
|
|
|
|
xswda.event_mask = KeyPressMask | KeyReleaseMask | ExposureMask | VisibilityChangeMask | FocusChangeMask /* mmm */;
|
|
xswda.colormap = cmap;
|
|
|
|
window = XCreateWindow(display,
|
|
XRootWindowOfScreen(screen),
|
|
50, 50,
|
|
window_width, window_height, 3, depth,
|
|
InputOutput, visual,
|
|
CWEventMask | CWBackPixel | CWColormap,
|
|
&xswda);
|
|
|
|
XStoreName(display, window, Atari800_TITLE);
|
|
#endif /* !defined(XVIEW) && !defined(MOTIF) */
|
|
|
|
#ifdef SHM
|
|
{
|
|
int major;
|
|
int minor;
|
|
Bool pixmaps;
|
|
Status status;
|
|
int shmsize;
|
|
|
|
status = XShmQueryVersion(display, &major, &minor, &pixmaps);
|
|
if (!status) {
|
|
printf("X Shared Memory extensions not available\n");
|
|
exit(1);
|
|
}
|
|
printf("Using X11 Shared Memory Extensions\n");
|
|
|
|
image = XShmCreateImage(display, visual, depth, ZPixmap,
|
|
NULL, &shminfo, window_width, window_height);
|
|
shmsize = (window_width * window_height *
|
|
image->bits_per_pixel) / 8;
|
|
|
|
shminfo.shmid = shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0777);
|
|
shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0);
|
|
shminfo.readOnly = False;
|
|
|
|
XShmAttach(display, &shminfo);
|
|
|
|
XSync(display, False);
|
|
|
|
shmctl(shminfo.shmid, IPC_RMID, 0);
|
|
|
|
}
|
|
#else
|
|
pixmap = XCreatePixmap(display, window,
|
|
window_width, window_height, depth);
|
|
#endif /* SHM */
|
|
|
|
PLATFORM_PaletteUpdate();
|
|
|
|
#ifndef SHM
|
|
XFillRectangle(display, pixmap, gc, 0, 0,
|
|
window_width, window_height);
|
|
for (i = 0; i < NRECTS; i++)
|
|
rectangles[i].height = (windowsize == Huge) ? 3 : 2;
|
|
#endif
|
|
|
|
XMapWindow(display, window);
|
|
|
|
XSync(display, False);
|
|
autorepeat_get();
|
|
|
|
/*
|
|
============================
|
|
Storage for Atari 800 Screen
|
|
============================
|
|
*/
|
|
image_data = (UBYTE *) Util_malloc(Screen_WIDTH * Screen_HEIGHT);
|
|
memset(image_data, 0, Screen_WIDTH * Screen_HEIGHT);
|
|
|
|
keyboard_consol = INPUT_CONSOL_NONE;
|
|
|
|
if (x11bug) {
|
|
printf("Initial X11 controller configuration\n");
|
|
printf("------------------------------------\n\n");
|
|
printf("Keypad is ");
|
|
Atari_WhatIs(keypad_mode);
|
|
printf("\n");
|
|
printf("Mouse is ");
|
|
Atari_WhatIs(xmouse_mode);
|
|
printf("\n");
|
|
printf("/dev/js0 is ");
|
|
Atari_WhatIs(js0_mode);
|
|
printf("\n");
|
|
printf("/dev/js1 is ");
|
|
Atari_WhatIs(js1_mode);
|
|
printf("\n");
|
|
}
|
|
signal(SIGSEGV, segmentationfault);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int PLATFORM_Exit(int run_monitor)
|
|
{
|
|
int restart;
|
|
|
|
Log_flushlog();
|
|
if (run_monitor) {
|
|
autorepeat_restore();
|
|
restart = MONITOR_Run();
|
|
autorepeat_off();
|
|
}
|
|
else
|
|
restart = FALSE;
|
|
|
|
if (!restart) {
|
|
if (image_data != NULL)
|
|
free(image_data);
|
|
|
|
if (display != NULL) {
|
|
XSync(display, True);
|
|
|
|
if (private_cmap)
|
|
XFreeColormap(display, cmap);
|
|
|
|
#ifdef SHM
|
|
if (image != NULL)
|
|
XDestroyImage(image);
|
|
#else
|
|
XFreePixmap(display, pixmap);
|
|
#endif
|
|
XUnmapWindow(display, window);
|
|
XDestroyWindow(display, window);
|
|
autorepeat_restore();
|
|
XCloseDisplay(display);
|
|
}
|
|
|
|
#ifdef LINUX_JOYSTICK
|
|
if (js0 != -1)
|
|
close(js0);
|
|
|
|
if (js1 != -1)
|
|
close(js1);
|
|
#endif
|
|
|
|
}
|
|
return restart;
|
|
}
|
|
|
|
void PLATFORM_DisplayScreen(void)
|
|
{
|
|
static char status_line[64];
|
|
int update_status_line = FALSE;
|
|
|
|
if (!invisible) {
|
|
const UBYTE *ptr2 = (const UBYTE *) Screen_atari + clipping_y * Screen_WIDTH + clipping_x;
|
|
|
|
#ifdef SHM
|
|
|
|
int first_x = Screen_WIDTH;
|
|
int last_x = -1000;
|
|
int first_y = Screen_HEIGHT;
|
|
int last_y = -1000;
|
|
int x;
|
|
int y;
|
|
|
|
#define SHM_SET_LAST \
|
|
last_y = y; \
|
|
if (x > last_x) \
|
|
last_x = x; \
|
|
if (x < first_x) \
|
|
first_x = x;
|
|
|
|
#define SHM_DISPLAY_SCREEN(pixel_type) \
|
|
pixel_type *ptr = (pixel_type *) image->data; \
|
|
pixel_type help_color; \
|
|
if (windowsize == Small) { \
|
|
for (y = clipping_y; y < (clipping_y + clipping_height); y++) { \
|
|
for (x = clipping_x; x < (clipping_x + clipping_width); x++) { \
|
|
help_color = colours[*ptr2++]; \
|
|
if (help_color != *ptr || force_redraw) { \
|
|
SHM_SET_LAST \
|
|
*ptr = help_color; \
|
|
} \
|
|
ptr++; \
|
|
} \
|
|
if (first_y > last_y && last_y >= 0) \
|
|
first_y = last_y; \
|
|
ptr2 += Screen_WIDTH - clipping_width; \
|
|
} \
|
|
} \
|
|
else if (windowsize == Large) { \
|
|
for (y = clipping_y; y < (clipping_y + clipping_height); y++) { \
|
|
pixel_type *ptr_second_line = ptr + window_width; \
|
|
for (x = clipping_x; x < (clipping_x + clipping_width); x++) { \
|
|
help_color = colours[*ptr2++]; \
|
|
if (help_color != *ptr || force_redraw) { \
|
|
SHM_SET_LAST \
|
|
ptr[0] = help_color; \
|
|
ptr[1] = help_color; \
|
|
ptr_second_line[0] = help_color; \
|
|
ptr_second_line[1] = help_color; \
|
|
} \
|
|
ptr += 2; \
|
|
ptr_second_line += 2; \
|
|
} \
|
|
if (first_y > last_y && last_y >= 0) \
|
|
first_y = last_y; \
|
|
ptr2 += Screen_WIDTH - clipping_width; \
|
|
ptr += window_width; \
|
|
} \
|
|
} \
|
|
else { \
|
|
for (y = clipping_y; y < (clipping_y + clipping_height); y++) { \
|
|
pixel_type *ptr_second_line = ptr + window_width; \
|
|
pixel_type *ptr_third_line = ptr + window_width + window_width; \
|
|
for (x = clipping_x; x < (clipping_x + clipping_width); x++) { \
|
|
help_color = colours[*ptr2++]; \
|
|
if (help_color != *ptr || force_redraw) { \
|
|
SHM_SET_LAST \
|
|
ptr[0] = help_color; \
|
|
ptr[1] = help_color; \
|
|
ptr[2] = help_color; \
|
|
ptr_second_line[0] = help_color; \
|
|
ptr_second_line[1] = help_color; \
|
|
ptr_second_line[2] = help_color; \
|
|
ptr_third_line[0] = help_color; \
|
|
ptr_third_line[1] = help_color; \
|
|
ptr_third_line[2] = help_color; \
|
|
} \
|
|
ptr += 3; \
|
|
ptr_second_line += 3; \
|
|
ptr_third_line += 3; \
|
|
} \
|
|
if (first_y > last_y && last_y >= 0) \
|
|
first_y = last_y; \
|
|
ptr2 += Screen_WIDTH - clipping_width; \
|
|
ptr += window_width + window_width; \
|
|
} \
|
|
}
|
|
|
|
if (image->bits_per_pixel == 32) {
|
|
SHM_DISPLAY_SCREEN(ULONG)
|
|
}
|
|
else if (image->bits_per_pixel == 16) {
|
|
SHM_DISPLAY_SCREEN(UWORD)
|
|
}
|
|
else if (image->bits_per_pixel == 8) {
|
|
SHM_DISPLAY_SCREEN(UBYTE)
|
|
}
|
|
|
|
if (modified) {
|
|
XShmPutImage(display, window, gc, image, 0, 0, 0, 0,
|
|
window_width, window_height, 0);
|
|
modified = FALSE;
|
|
}
|
|
else if (last_y >= 0) {
|
|
last_x++;
|
|
last_y++;
|
|
if (first_x < clipping_x)
|
|
first_x = clipping_x;
|
|
if (last_x > clipping_x + clipping_width)
|
|
last_x = clipping_x + clipping_width;
|
|
else if (last_x <= first_x)
|
|
last_x = first_x + 1;
|
|
if (first_y < clipping_y)
|
|
first_y = clipping_y;
|
|
if (last_y > clipping_y + clipping_height)
|
|
last_y = clipping_y + clipping_height;
|
|
else if (last_y <= first_y)
|
|
last_y = first_y + 1;
|
|
|
|
first_x *= clipping_factor;
|
|
last_x *= clipping_factor;
|
|
first_y *= clipping_factor;
|
|
last_y *= clipping_factor;
|
|
|
|
XShmPutImage(display, window, gc, image,
|
|
first_x - (clipping_x * clipping_factor),
|
|
first_y - (clipping_y * clipping_factor),
|
|
first_x - (clipping_x * clipping_factor),
|
|
first_y - (clipping_y * clipping_factor),
|
|
last_x - first_x, last_y - first_y, 0);
|
|
}
|
|
|
|
XSync(display, FALSE);
|
|
|
|
#else /* SHM */
|
|
|
|
UBYTE *ptr = image_data + clipping_y * Screen_WIDTH + clipping_x;
|
|
int n = 0;
|
|
int last_colour = -1;
|
|
int x;
|
|
int y;
|
|
|
|
switch (windowsize) {
|
|
case Small:
|
|
for (y = 0; y < clipping_height; y++) {
|
|
for (x = 0; x < clipping_width; x++) {
|
|
UBYTE colour = *ptr2++;
|
|
if (colour != *ptr || force_redraw) {
|
|
*ptr = colour;
|
|
if (colour != last_colour || n >= NPOINTS) {
|
|
if (n > 0) {
|
|
XDrawPoints(display, pixmap, gc_colour[last_colour],
|
|
points, n, CoordModeOrigin);
|
|
n = 0;
|
|
modified = TRUE;
|
|
}
|
|
last_colour = colour;
|
|
}
|
|
points[n].x = x;
|
|
points[n].y = y;
|
|
n++;
|
|
}
|
|
ptr++;
|
|
}
|
|
ptr += Screen_WIDTH - clipping_width;
|
|
ptr2 += Screen_WIDTH - clipping_width;
|
|
}
|
|
if (n > 0) {
|
|
XDrawPoints(display, pixmap, gc_colour[last_colour],
|
|
points, n, CoordModeOrigin);
|
|
modified = TRUE;
|
|
}
|
|
break;
|
|
case Large:
|
|
for (y = 0; y < window_height; y += 2) {
|
|
for (x = 0; x < window_width; ) {
|
|
UBYTE colour = *ptr2++;
|
|
if (colour != *ptr || force_redraw) {
|
|
int width = 2;
|
|
*ptr++ = colour;
|
|
if (colour != last_colour || n >= NRECTS) {
|
|
if (n > 0) {
|
|
XFillRectangles(display, pixmap, gc_colour[last_colour],
|
|
rectangles, n);
|
|
n = 0;
|
|
modified = TRUE;
|
|
}
|
|
last_colour = colour;
|
|
}
|
|
rectangles[n].x = x;
|
|
rectangles[n].y = y;
|
|
while ((x += 2) < window_width && colour == *ptr2 && colour != *ptr) {
|
|
width += 2;
|
|
ptr2++;
|
|
*ptr++ = colour;
|
|
}
|
|
rectangles[n].width = width;
|
|
/* rectangles[n].height = 2; */
|
|
n++;
|
|
continue;
|
|
}
|
|
ptr++;
|
|
x += 2;
|
|
}
|
|
ptr += Screen_WIDTH - clipping_width;
|
|
ptr2 += Screen_WIDTH - clipping_width;
|
|
}
|
|
if (n > 0) {
|
|
XFillRectangles(display, pixmap, gc_colour[last_colour],
|
|
rectangles, n);
|
|
modified = TRUE;
|
|
}
|
|
break;
|
|
case Huge:
|
|
for (y = 0; y < window_height; y += 3) {
|
|
for (x = 0; x < window_width; ) {
|
|
UBYTE colour = *ptr2++;
|
|
if (colour != *ptr || force_redraw) {
|
|
int width = 3;
|
|
*ptr++ = colour;
|
|
if (colour != last_colour || n >= NRECTS) {
|
|
if (n > 0) {
|
|
XFillRectangles(display, pixmap, gc_colour[last_colour],
|
|
rectangles, n);
|
|
n = 0;
|
|
modified = TRUE;
|
|
}
|
|
last_colour = colour;
|
|
}
|
|
rectangles[n].x = x;
|
|
rectangles[n].y = y;
|
|
while ((x += 3) < window_width && colour == *ptr2 && colour != *ptr) {
|
|
width += 3;
|
|
ptr2++;
|
|
*ptr++ = colour;
|
|
}
|
|
rectangles[n].width = width;
|
|
/* rectangles[n].height = 3; */
|
|
n++;
|
|
continue;
|
|
}
|
|
ptr++;
|
|
x += 3;
|
|
}
|
|
ptr2 += Screen_WIDTH - clipping_width;
|
|
ptr += Screen_WIDTH - clipping_width;
|
|
}
|
|
if (n > 0) {
|
|
XFillRectangles(display, pixmap, gc_colour[last_colour],
|
|
rectangles, n);
|
|
modified = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (modified) {
|
|
XCopyArea(display, pixmap, window, gc, 0, 0,
|
|
window_width, window_height, 0, 0);
|
|
XSync(display, FALSE);
|
|
modified = FALSE;
|
|
}
|
|
|
|
#endif /* SHM */
|
|
|
|
}
|
|
|
|
switch (x11_monitor) {
|
|
case MONITOR_SIO:
|
|
if (SIO_status[0] != '\0') {
|
|
#ifdef XVIEW
|
|
strcpy(status_line, SIO_status);
|
|
#else
|
|
sprintf(status_line, "%s - %s",
|
|
Atari800_TITLE, SIO_status);
|
|
#endif
|
|
SIO_status[0] = '\0';
|
|
update_status_line = TRUE;
|
|
}
|
|
else {
|
|
update_status_line = FALSE;
|
|
}
|
|
break;
|
|
default:
|
|
update_status_line = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (update_status_line) {
|
|
#ifdef XVIEW
|
|
xv_set(frame,
|
|
FRAME_LEFT_FOOTER, status_line,
|
|
NULL);
|
|
#else
|
|
#ifdef MOTIF
|
|
XtVaSetValues(toplevel,
|
|
XtNtitle, status_line,
|
|
NULL);
|
|
#else
|
|
XStoreName(display, window, status_line);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
int PLATFORM_Keyboard(void)
|
|
{
|
|
static int keycode = AKEY_NONE;
|
|
|
|
#ifdef XVIEW
|
|
notify_dispatch();
|
|
XFlush(display);
|
|
#endif
|
|
|
|
#ifdef MOTIF
|
|
while (XtAppPending(app)) {
|
|
static XEvent event;
|
|
|
|
XtAppNextEvent(app, &event);
|
|
XtDispatchEvent(&event);
|
|
}
|
|
#endif
|
|
|
|
#if defined(XVIEW) || defined(MOTIF)
|
|
keycode = xview_keycode;
|
|
#else
|
|
if (XEventsQueued(display, QueuedAfterFlush) > 0) {
|
|
XEvent event;
|
|
|
|
XNextEvent(display, &event);
|
|
keycode = GetKeyCode(&event);
|
|
}
|
|
#endif
|
|
|
|
return keycode;
|
|
}
|
|
|
|
#if 0
|
|
void experimental_mouse_joystick(int mode) /* Don't use ;-) */
|
|
{
|
|
Window root_return;
|
|
Window child_return;
|
|
int root_x_return;
|
|
int root_y_return;
|
|
int win_x_return;
|
|
int win_y_return;
|
|
int mask_return;
|
|
|
|
static int prev_x=-1,prev_y=-1;
|
|
|
|
XQueryPointer(display, window, &root_return, &child_return,
|
|
&root_x_return, &root_y_return,
|
|
&win_x_return, &win_y_return,
|
|
&mask_return);
|
|
|
|
if (mode < 5) {
|
|
int dx,dy;
|
|
int course,rc;
|
|
|
|
if( prev_x<0 ) prev_x=root_x_return;
|
|
if( prev_y<0 ) prev_y=root_y_return;
|
|
dx=(root_x_return-prev_x)<<1;
|
|
dy=(root_y_return-prev_y)*3;
|
|
#define Ms 8
|
|
#define Mc 3 /* Mc/Mm = 2 45 deg. <2 => >45 deg for x or y only */
|
|
#define Mm 2
|
|
if( dx>Ms && dy>Ms )
|
|
{ if( dx*Mm>Mc*dy )
|
|
course = 0x08; /* RIGHT */
|
|
else if ( dx*Mc<dy*Mm )
|
|
course = 0x02; /* DOWN */
|
|
else course = 0x0a; /* RIGHT DOWN */
|
|
} else if( dx<-Ms && dy<-Ms )
|
|
{ if( dx*Mm<Mc*dy )
|
|
course = 0x04; /* LEFT */
|
|
else if ( dx*Mc>dy*Mm )
|
|
course = 0x01; /* UP */
|
|
else course = 0x05; /* LEFT UP */
|
|
} else if( dx<-Ms && dy>Ms )
|
|
{ if( -dx*Mm>Mc*dy )
|
|
course = 0x04; /* LEFT */
|
|
else if ( -dx*Mc<dy*Mm )
|
|
course = 0x02; /* DOWN */
|
|
else course = 0x06; /* LEFT DOWN */
|
|
} else if( dx>Ms && dy<-Ms )
|
|
{ if( -dx*Mm<Mc*dy )
|
|
course = 0x08; /* RIGHT */
|
|
else if ( -dx*Mc>dy*Mm )
|
|
course = 0x01; /* UP */
|
|
else course = 0x09; /* RIGHT UP */
|
|
}
|
|
else if( dx>Ms )
|
|
course = 0x08; /* RIGHT */
|
|
else if( dx<-Ms )
|
|
course = 0x04; /* LEFT */
|
|
else if( dy>Ms )
|
|
course = 0x02; /* DOWN */
|
|
else if( dy<-Ms )
|
|
course = 0x01; /* UP */
|
|
else course=0;
|
|
|
|
rc=(((course&0x5)<<1)|((course&0xa)>>1));
|
|
rc&= ~mouse_stick;
|
|
mouse_stick|=rc;
|
|
course&=~(((rc&0x5)<<1)|((rc&0xa)>>1));
|
|
mouse_stick&=~course;
|
|
|
|
prev_x=root_x_return;
|
|
prev_y=root_y_return;
|
|
}
|
|
else {
|
|
if (mask_return)
|
|
mouse_stick &= 0xfb;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static void mouse_joystick(int mode)
|
|
{
|
|
Window root_return;
|
|
Window child_return;
|
|
int root_x_return;
|
|
int root_y_return;
|
|
int win_x_return;
|
|
int win_y_return;
|
|
unsigned int mask_return;
|
|
|
|
mouse_stick = 0x0f;
|
|
|
|
XQueryPointer(display, window, &root_return, &child_return,
|
|
&root_x_return, &root_y_return,
|
|
&win_x_return, &win_y_return,
|
|
&mask_return);
|
|
|
|
if (mode < 5) {
|
|
int center_x;
|
|
int center_y;
|
|
int threshold;
|
|
|
|
if (windowsize == Small) {
|
|
center_x = window_width / 2;
|
|
center_y = window_height / 2;
|
|
threshold = 32;
|
|
}
|
|
else if (windowsize == Large) {
|
|
center_x = window_width / 2;
|
|
center_y = window_height / 2;
|
|
threshold = 64;
|
|
}
|
|
else {
|
|
center_x = window_width / 2;
|
|
center_y = window_height / 2;
|
|
threshold = 96;
|
|
}
|
|
|
|
if (win_x_return < 0 || win_x_return > center_x * 2 ||
|
|
win_y_return < 0 || win_y_return > center_y * 2 )
|
|
mouse_stick = 0x0f;
|
|
else
|
|
{
|
|
if (win_x_return < (center_x - threshold))
|
|
mouse_stick &= 0xfb;
|
|
if (win_x_return > (center_x + threshold))
|
|
mouse_stick &= 0xf7;
|
|
if (win_y_return < (center_y - threshold))
|
|
mouse_stick &= 0xfe;
|
|
if (win_y_return > (center_y + threshold))
|
|
mouse_stick &= 0xfd;
|
|
}
|
|
}
|
|
else {
|
|
if (mask_return)
|
|
mouse_stick &= 0xfb;
|
|
}
|
|
}
|
|
|
|
#ifdef LINUX_JOYSTICK
|
|
|
|
static void read_joystick(int js, int centre_x, int centre_y)
|
|
{
|
|
const int threshold = 50;
|
|
int status;
|
|
|
|
mouse_stick = 0x0f;
|
|
|
|
status = read(js, &js_data, JS_RETURN);
|
|
if (status != JS_RETURN) {
|
|
perror("/dev/js");
|
|
exit(1);
|
|
}
|
|
if (js_data.x < (centre_x - threshold))
|
|
mouse_stick &= 0xfb;
|
|
if (js_data.x > (centre_x + threshold))
|
|
mouse_stick &= 0xf7;
|
|
if (js_data.y < (centre_y - threshold))
|
|
mouse_stick &= 0xfe;
|
|
if (js_data.y > (centre_y + threshold))
|
|
mouse_stick &= 0xfd;
|
|
}
|
|
#endif
|
|
|
|
int PLATFORM_PORT(int num)
|
|
{
|
|
int nibble_0 = 0x0f;
|
|
int nibble_1 = 0x0f;
|
|
|
|
if (num == 0) {
|
|
if (keypad_mode == 0)
|
|
nibble_0 = keypad_stick;
|
|
else if (keypad_mode == 1)
|
|
nibble_1 = keypad_stick;
|
|
|
|
if (INPUT_mouse_mode == INPUT_MOUSE_OFF) {
|
|
if (xmouse_mode == 0) {
|
|
mouse_joystick(xmouse_mode);
|
|
nibble_0 = mouse_stick;
|
|
}
|
|
else if (xmouse_mode == 1) {
|
|
mouse_joystick(xmouse_mode);
|
|
nibble_1 = mouse_stick;
|
|
}
|
|
}
|
|
#ifdef LINUX_JOYSTICK
|
|
if (js0_mode == 0) {
|
|
read_joystick(js0, js0_centre_x, js0_centre_y);
|
|
nibble_0 = mouse_stick;
|
|
}
|
|
else if (js0_mode == 1) {
|
|
read_joystick(js0, js0_centre_x, js0_centre_y);
|
|
nibble_1 = mouse_stick;
|
|
}
|
|
if (js1_mode == 0) {
|
|
read_joystick(js1, js1_centre_x, js1_centre_y);
|
|
nibble_0 = mouse_stick;
|
|
}
|
|
else if (js1_mode == 1) {
|
|
read_joystick(js1, js1_centre_x, js1_centre_y);
|
|
nibble_1 = mouse_stick;
|
|
}
|
|
#endif
|
|
}
|
|
else {
|
|
if (keypad_mode == 2)
|
|
nibble_0 = keypad_stick;
|
|
else if (keypad_mode == 3)
|
|
nibble_1 = keypad_stick;
|
|
|
|
if (INPUT_mouse_mode == INPUT_MOUSE_OFF) {
|
|
if (xmouse_mode == 2) {
|
|
mouse_joystick(xmouse_mode);
|
|
nibble_0 = mouse_stick;
|
|
}
|
|
else if (xmouse_mode == 3) {
|
|
mouse_joystick(xmouse_mode);
|
|
nibble_1 = mouse_stick;
|
|
}
|
|
}
|
|
|
|
#ifdef LINUX_JOYSTICK
|
|
if (js0_mode == 2) {
|
|
read_joystick(js0, js0_centre_x, js0_centre_y);
|
|
nibble_0 = mouse_stick;
|
|
}
|
|
else if (js0_mode == 3) {
|
|
read_joystick(js0, js0_centre_x, js0_centre_y);
|
|
nibble_1 = mouse_stick;
|
|
}
|
|
if (js1_mode == 2) {
|
|
read_joystick(js1, js1_centre_x, js1_centre_y);
|
|
nibble_0 = mouse_stick;
|
|
}
|
|
else if (js1_mode == 3) {
|
|
read_joystick(js1, js1_centre_x, js1_centre_y);
|
|
nibble_1 = mouse_stick;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return (nibble_1 << 4) | nibble_0;
|
|
}
|
|
|
|
int PLATFORM_TRIG(int num)
|
|
{
|
|
int trig = 1; /* Trigger not pressed */
|
|
|
|
if (num == keypad_mode) {
|
|
trig = keypad_trig;
|
|
}
|
|
if (num == xmouse_mode) {
|
|
Window root_return;
|
|
Window child_return;
|
|
int root_x_return;
|
|
int root_y_return;
|
|
int win_x_return;
|
|
int win_y_return;
|
|
unsigned int mask_return;
|
|
|
|
if (XQueryPointer(display, window, &root_return, &child_return,
|
|
&root_x_return, &root_y_return,
|
|
&win_x_return, &win_y_return,
|
|
&mask_return)) {
|
|
if (win_x_return < 0 || win_x_return > window_width ||
|
|
win_y_return < 0 || win_y_return > window_height)
|
|
trig = 1;
|
|
else if (mask_return & Button1Mask)
|
|
trig = 0;
|
|
}
|
|
}
|
|
#ifdef LINUX_JOYSTICK
|
|
if (num == js0_mode) {
|
|
int status;
|
|
|
|
status = read(js0, &js_data, JS_RETURN);
|
|
if (status != JS_RETURN) {
|
|
perror("/dev/js0");
|
|
exit(1);
|
|
}
|
|
if (js_data.buttons & 0x01)
|
|
trig = 0;
|
|
else
|
|
trig = 1;
|
|
}
|
|
if (num == js1_mode) {
|
|
int status;
|
|
|
|
status = read(js1, &js_data, JS_RETURN);
|
|
if (status != JS_RETURN) {
|
|
perror("/dev/js1");
|
|
exit(1);
|
|
}
|
|
trig = (js_data.buttons & 0x0f) ? 0 : 1;
|
|
}
|
|
#endif
|
|
|
|
return trig;
|
|
}
|
|
|
|
void PLATFORM_PaletteUpdate(void)
|
|
{
|
|
int i, j;
|
|
int depth;
|
|
int colorstep;
|
|
XGCValues xgcvl;
|
|
|
|
depth = XDefaultDepthOfScreen(screen);
|
|
cmap = XDefaultColormapOfScreen(screen);
|
|
|
|
if (depth <= 8)
|
|
colorstep = 2;
|
|
else
|
|
colorstep = 1;
|
|
|
|
if (colors_allocated) {
|
|
if (colorstep == 1)
|
|
XFreeColors(display, cmap, colours, 256, 0);
|
|
else {
|
|
for (i = 0; i < 256; i += colorstep)
|
|
XFreeColors(display, cmap, colours + i, 1, 0);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 256; i += colorstep) {
|
|
XColor colour;
|
|
|
|
int rgb = Colours_table[i];
|
|
int status;
|
|
|
|
colour.red = (rgb & 0x00ff0000) >> 8;
|
|
colour.green = (rgb & 0x0000ff00);
|
|
colour.blue = (rgb & 0x000000ff) << 8;
|
|
|
|
status = XAllocColor(display,
|
|
cmap,
|
|
&colour);
|
|
|
|
if (! status) {
|
|
printf("Could not allocate color\n");
|
|
exit(1);
|
|
}
|
|
|
|
for (j = 0; j < colorstep; j++)
|
|
colours[i + j] = colour.pixel;
|
|
|
|
#ifdef SHM
|
|
#ifdef USE_COLOUR_TRANSLATION_TABLE
|
|
for (j = 0; j < colorstep; j++)
|
|
colour_translation_table[i + j] = colours[i + j] | (colours[i + j] << 8);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
if (! colors_allocated) {
|
|
for (i = 0; i < 256; i++) {
|
|
xgcvl.background = colours[0];
|
|
xgcvl.foreground = colours[i];
|
|
|
|
gc_colour[i] = XCreateGC(display, window,
|
|
GCForeground | GCBackground,
|
|
&xgcvl);
|
|
}
|
|
|
|
xgcvl.background = colours[0];
|
|
xgcvl.foreground = colours[0];
|
|
|
|
gc = XCreateGC(display, window,
|
|
GCForeground | GCBackground,
|
|
&xgcvl);
|
|
|
|
}
|
|
else {
|
|
for (i = 0; i < 256; i++) {
|
|
xgcvl.background = colours[0];
|
|
xgcvl.foreground = colours[i];
|
|
|
|
XChangeGC(display, gc_colour[i],
|
|
GCForeground | GCBackground,
|
|
&xgcvl);
|
|
}
|
|
|
|
xgcvl.background = colours[0];
|
|
xgcvl.foreground = colours[0];
|
|
|
|
XChangeGC(display, gc,
|
|
GCForeground | GCBackground,
|
|
&xgcvl);
|
|
|
|
force_redraw = TRUE;
|
|
PLATFORM_DisplayScreen();
|
|
force_redraw = FALSE;
|
|
}
|
|
colors_allocated = TRUE;
|
|
}
|
|
|
|
void Atari_Mouse(void)
|
|
{
|
|
static int last_x = 0;
|
|
static int last_y = 0;
|
|
Window root_return;
|
|
Window child_return;
|
|
int root_x_return;
|
|
int root_y_return;
|
|
int win_x_return;
|
|
int win_y_return;
|
|
unsigned int mask_return;
|
|
|
|
if (INPUT_mouse_mode == INPUT_MOUSE_OFF)
|
|
return;
|
|
if (XQueryPointer(display, window, &root_return,
|
|
&child_return, &root_x_return, &root_y_return,
|
|
&win_x_return, &win_y_return, &mask_return)) {
|
|
if(INPUT_direct_mouse) {
|
|
int potx = win_x_return, poty = win_y_return;
|
|
if(potx < 0) potx = 0;
|
|
if(poty < 0) poty = 0;
|
|
potx = (double)potx * (228.0 / (double)window_width);
|
|
poty = (double)poty * (228.0 / (double)window_height);
|
|
if(potx > 227) potx = 227;
|
|
if(poty > 227) poty = 227;
|
|
POKEY_POT_input[INPUT_mouse_port << 1] = 227 - potx;
|
|
POKEY_POT_input[(INPUT_mouse_port << 1) + 1] = 227 - poty;
|
|
} else {
|
|
INPUT_mouse_delta_x = win_x_return - last_x;
|
|
INPUT_mouse_delta_y = win_y_return - last_y;
|
|
last_x = win_x_return;
|
|
last_y = win_y_return;
|
|
}
|
|
|
|
INPUT_mouse_buttons = (mask_return & Button1Mask ? 1 : 0)
|
|
| (mask_return & Button3Mask ? 2 : 0)
|
|
| (mask_return & Button2Mask ? 4 : 0);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
/* initialise Atari800 core */
|
|
if (!Atari800_Initialise(&argc, argv))
|
|
return 3;
|
|
|
|
/* main loop */
|
|
for (;;) {
|
|
INPUT_key_code = PLATFORM_Keyboard();
|
|
|
|
if (menu_consol != INPUT_CONSOL_NONE) {
|
|
INPUT_key_consol = menu_consol;
|
|
menu_consol = INPUT_CONSOL_NONE;
|
|
}
|
|
else
|
|
INPUT_key_consol = keyboard_consol;
|
|
|
|
Atari_Mouse();
|
|
|
|
Atari800_Frame();
|
|
if (Atari800_display_screen)
|
|
PLATFORM_DisplayScreen();
|
|
}
|
|
}
|