1762 lines
36 KiB
C
1762 lines
36 KiB
C
/*
|
|
OSGLUGTK.c
|
|
|
|
Copyright (C) 2009 Paul C. Pratt
|
|
|
|
You can redistribute this file and/or modify it under the terms
|
|
of version 2 of the GNU General Public License as published by
|
|
the Free Software Foundation. You should have received a copy
|
|
of the license along with this file; see the file COPYING.
|
|
|
|
This file 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
|
|
license for more details.
|
|
*/
|
|
|
|
/*
|
|
Operating System GLUe for GTK
|
|
|
|
All operating system dependent code for the
|
|
GIMP Toolkit should go here.
|
|
*/
|
|
|
|
#include "CNFGRAPI.h"
|
|
#include "SYSDEPNS.h"
|
|
#include "ENDIANAC.h"
|
|
|
|
#include "UI/MYOSGLUE.h"
|
|
|
|
#include "STRCONST.h"
|
|
|
|
#include "COMOSGLU.h"
|
|
|
|
/* --- some simple utilities --- */
|
|
|
|
GLOBALOSGLUPROC MoveBytes(anyp srcPtr, anyp destPtr, int32_t byteCount)
|
|
{
|
|
(void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
|
|
}
|
|
|
|
/* --- control mode and internationalization --- */
|
|
|
|
#define NeedCell2PlainAsciiMap 1
|
|
|
|
#include "INTLCHAR.h"
|
|
|
|
#include "CONTROLM.h"
|
|
|
|
/* --- sending debugging info to file --- */
|
|
|
|
#if dbglog_HAVE
|
|
|
|
#define dbglog_ToStdErr 0
|
|
|
|
#if ! dbglog_ToStdErr
|
|
LOCALVAR FILE *dbglog_File = NULL;
|
|
#endif
|
|
|
|
LOCALFUNC bool dbglog_open0(void)
|
|
{
|
|
#if dbglog_ToStdErr
|
|
return true;
|
|
#else
|
|
dbglog_File = fopen("dbglog.txt", "w");
|
|
return (NULL != dbglog_File);
|
|
#endif
|
|
}
|
|
|
|
LOCALPROC dbglog_write0(char *s, uimr L)
|
|
{
|
|
#if dbglog_ToStdErr
|
|
(void) fwrite(s, 1, L, stderr);
|
|
#else
|
|
if (dbglog_File != NULL) {
|
|
(void) fwrite(s, 1, L, dbglog_File);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
LOCALPROC dbglog_close0(void)
|
|
{
|
|
#if ! dbglog_ToStdErr
|
|
if (dbglog_File != NULL) {
|
|
fclose(dbglog_File);
|
|
dbglog_File = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#endif
|
|
|
|
/* --- debug settings and utilities --- */
|
|
|
|
#define DbgEvents (dbglog_HAVE && 1)
|
|
|
|
#if ! dbglog_HAVE
|
|
#define WriteExtraErr(s)
|
|
#else
|
|
LOCALPROC WriteExtraErr(char *s)
|
|
{
|
|
dbglog_writeCStr("*** error: ");
|
|
dbglog_writeCStr(s);
|
|
dbglog_writeReturn();
|
|
}
|
|
#endif
|
|
|
|
/* --- text translation --- */
|
|
|
|
LOCALPROC NativeStrFromCStr(char *r, char *s, bool AddEllipsis)
|
|
{
|
|
uint8_t ps[ClStrMaxLength];
|
|
int i;
|
|
int L;
|
|
|
|
ClStrFromSubstCStr(&L, ps, s);
|
|
|
|
for (i = 0; i < L; ++i) {
|
|
r[i] = Cell2PlainAsciiMap[ps[i]];
|
|
}
|
|
|
|
if (AddEllipsis) {
|
|
r[L] = '.';
|
|
++L;
|
|
r[L] = '.';
|
|
++L;
|
|
r[L] = '.';
|
|
++L;
|
|
}
|
|
|
|
r[L] = 0;
|
|
}
|
|
|
|
/* --- drives --- */
|
|
|
|
#define NotAfileRef NULL
|
|
|
|
LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */
|
|
|
|
LOCALPROC InitDrives(void)
|
|
{
|
|
/*
|
|
This isn't really needed, Drives[i] and DriveNames[i]
|
|
need not have valid values when not vSonyIsInserted[i].
|
|
*/
|
|
tDrive i;
|
|
|
|
for (i = 0; i < NumDrives; ++i) {
|
|
Drives[i] = NotAfileRef;
|
|
}
|
|
}
|
|
|
|
GLOBALOSGLUFUNC tMacErr vSonyTransfer(bool IsWrite, uint8_t * Buffer,
|
|
tDrive Drive_No, uint32_t Sony_Start, uint32_t Sony_Count,
|
|
uint32_t *Sony_ActCount)
|
|
{
|
|
uint32_t NewSony_Count = Sony_Count;
|
|
|
|
fseek(Drives[Drive_No], Sony_Start, SEEK_SET);
|
|
|
|
if (IsWrite) {
|
|
fwrite(Buffer, 1, NewSony_Count, Drives[Drive_No]);
|
|
} else {
|
|
fread(Buffer, 1, NewSony_Count, Drives[Drive_No]);
|
|
}
|
|
|
|
if (nullpr != Sony_ActCount) {
|
|
*Sony_ActCount = NewSony_Count;
|
|
}
|
|
|
|
return mnvm_noErr; /*& figure out what really to return &*/
|
|
}
|
|
|
|
GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, uint32_t *Sony_Count)
|
|
{
|
|
fseek(Drives[Drive_No], 0, SEEK_END);
|
|
*Sony_Count = ftell(Drives[Drive_No]);
|
|
return mnvm_noErr; /*& figure out what really to return &*/
|
|
}
|
|
|
|
LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, bool deleteit)
|
|
{
|
|
DiskEjectedNotify(Drive_No);
|
|
|
|
fclose(Drives[Drive_No]);
|
|
Drives[Drive_No] = NotAfileRef; /* not really needed */
|
|
|
|
|
|
return mnvm_noErr;
|
|
}
|
|
|
|
GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
|
|
{
|
|
return vSonyEject0(Drive_No, false);
|
|
}
|
|
|
|
LOCALPROC UnInitDrives(void)
|
|
{
|
|
tDrive i;
|
|
|
|
for (i = 0; i < NumDrives; ++i) {
|
|
if (vSonyIsInserted(i)) {
|
|
(void) vSonyEject(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCALFUNC bool Sony_Insert0(FILE *refnum, bool locked,
|
|
char *drivepath)
|
|
{
|
|
tDrive Drive_No;
|
|
|
|
if (! FirstFreeDisk(&Drive_No)) {
|
|
fclose(refnum);
|
|
MacMsg(kStrTooManyImagesTitle,
|
|
kStrTooManyImagesMessage, false);
|
|
return false;
|
|
} else {
|
|
/* printf("Sony_Insert0 %d\n", (int)Drive_No); */
|
|
Drives[Drive_No] = refnum;
|
|
DiskInsertNotify(Drive_No, locked);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
LOCALFUNC bool Sony_Insert1(char *drivepath, bool silentfail)
|
|
{
|
|
bool locked = false;
|
|
/* printf("Sony_Insert1 %s\n", drivepath); */
|
|
FILE *refnum = fopen(drivepath, "rb+");
|
|
if (NULL == refnum) {
|
|
locked = true;
|
|
refnum = fopen(drivepath, "rb");
|
|
}
|
|
if (NULL == refnum) {
|
|
if (! silentfail) {
|
|
MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, false);
|
|
}
|
|
} else {
|
|
return Sony_Insert0(refnum, locked, drivepath);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
LOCALFUNC tMacErr LoadMacRomFrom(char *path)
|
|
{
|
|
tMacErr err;
|
|
FILE *ROM_File;
|
|
int File_Size;
|
|
|
|
ROM_File = fopen(path, "rb");
|
|
if (NULL == ROM_File) {
|
|
err = mnvm_fnfErr;
|
|
} else {
|
|
File_Size = fread(ROM, 1, kROM_Size, ROM_File);
|
|
if (kROM_Size != File_Size) {
|
|
if (feof(ROM_File)) {
|
|
MacMsgOverride(kStrShortROMTitle,
|
|
kStrShortROMMessage);
|
|
err = mnvm_eofErr;
|
|
} else {
|
|
MacMsgOverride(kStrNoReadROMTitle,
|
|
kStrNoReadROMMessage);
|
|
err = mnvm_miscErr;
|
|
}
|
|
} else {
|
|
err = ROM_IsValid();
|
|
}
|
|
fclose(ROM_File);
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
LOCALFUNC bool Sony_Insert1a(char *drivepath, bool silentfail)
|
|
{
|
|
bool v;
|
|
|
|
if (! ROM_loaded) {
|
|
v = (mnvm_noErr == LoadMacRomFrom(drivepath));
|
|
} else {
|
|
v = Sony_Insert1(drivepath, silentfail);
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
LOCALFUNC bool Sony_InsertIth(int i)
|
|
{
|
|
bool v;
|
|
|
|
if ((i > 9) || ! FirstFreeDisk(nullpr)) {
|
|
v = false;
|
|
} else {
|
|
char s[] = "disk?.dsk";
|
|
|
|
s[4] = '0' + i;
|
|
|
|
v = Sony_Insert1(s, true);
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
LOCALFUNC bool LoadInitialImages(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 1; Sony_InsertIth(i); ++i) {
|
|
/* stop on first error (including file not found) */
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* --- ROM --- */
|
|
|
|
LOCALVAR char *rom_path = NULL;
|
|
|
|
LOCALFUNC bool LoadMacRom(void)
|
|
{
|
|
tMacErr err;
|
|
|
|
if ((NULL == rom_path)
|
|
|| (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path))))
|
|
if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName)))
|
|
{
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* --- video out --- */
|
|
|
|
static GtkWidget *drawing_area;
|
|
|
|
LOCALVAR bool gBackgroundFlag = false;
|
|
LOCALVAR bool gTrueBackgroundFlag = false;
|
|
LOCALVAR bool CurSpeedStopped = true;
|
|
|
|
LOCALPROC HaveChangedScreenBuff(int16_t top, int16_t left,
|
|
int16_t bottom, int16_t right)
|
|
{
|
|
guchar graybuf[vMacScreenWidth * vMacScreenHeight];
|
|
|
|
{
|
|
int i;
|
|
int j;
|
|
int k;
|
|
uint8_t *p1 = GetCurDrawBuff()
|
|
+ (uint32_t)vMacScreenWidth / 8 * top;
|
|
uint8_t *p2 = (uint8_t *)graybuf + (uint32_t)vMacScreenWidth * top;
|
|
uint32_t t0;
|
|
|
|
UnusedParam(left);
|
|
UnusedParam(right);
|
|
for (i = bottom - top; --i >= 0; ) {
|
|
for (j = vMacScreenWidth / 8; --j >= 0; ) {
|
|
t0 = *p1++;
|
|
for (k = 8; --k >= 0; ) {
|
|
*p2++ = ((t0 >> k) & 0x01) - 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
gdk_draw_gray_image(drawing_area->window,
|
|
drawing_area->style->fg_gc[GTK_WIDGET_STATE(drawing_area)],
|
|
left /* x */,
|
|
top /* y */,
|
|
right - left /* width */,
|
|
bottom - top /* height */,
|
|
GDK_RGB_DITHER_NONE,
|
|
graybuf + left + (uint32_t)vMacScreenWidth * top,
|
|
vMacScreenWidth);
|
|
}
|
|
|
|
LOCALPROC DrawChangesAndClear(void)
|
|
{
|
|
if (ScreenChangedBottom > ScreenChangedTop) {
|
|
HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
|
|
ScreenChangedBottom, ScreenChangedRight);
|
|
ScreenClearChanges();
|
|
}
|
|
}
|
|
|
|
GLOBALOSGLUPROC DoneWithDrawingForTick(void)
|
|
{
|
|
DrawChangesAndClear();
|
|
}
|
|
|
|
/* --- mouse --- */
|
|
|
|
LOCALVAR bool HaveCursorHidden = false;
|
|
LOCALVAR bool WantCursorHidden = false;
|
|
|
|
static GdkCursor *blank_cursor;
|
|
static GtkWidget *window = NULL;
|
|
|
|
LOCALPROC ForceShowCursor(void)
|
|
{
|
|
if (HaveCursorHidden) {
|
|
HaveCursorHidden = false;
|
|
|
|
if (window) {
|
|
gdk_window_set_cursor(window->window, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* cursor state */
|
|
|
|
LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv)
|
|
{
|
|
bool ShouldHaveCursorHidden = true;
|
|
|
|
{
|
|
if (NewMousePosh < 0) {
|
|
NewMousePosh = 0;
|
|
ShouldHaveCursorHidden = false;
|
|
} else if (NewMousePosh >= vMacScreenWidth) {
|
|
NewMousePosh = vMacScreenWidth - 1;
|
|
ShouldHaveCursorHidden = false;
|
|
}
|
|
if (NewMousePosv < 0) {
|
|
NewMousePosv = 0;
|
|
ShouldHaveCursorHidden = false;
|
|
} else if (NewMousePosv >= vMacScreenHeight) {
|
|
NewMousePosv = vMacScreenHeight - 1;
|
|
ShouldHaveCursorHidden = false;
|
|
}
|
|
|
|
|
|
/* if (ShouldHaveCursorHidden || CurMouseButton) */
|
|
/*
|
|
for a game like arkanoid, would like mouse to still
|
|
move even when outside window in one direction
|
|
*/
|
|
MousePositionSet(NewMousePosh, NewMousePosv);
|
|
}
|
|
|
|
WantCursorHidden = ShouldHaveCursorHidden;
|
|
}
|
|
|
|
LOCALPROC CheckMouseState(void)
|
|
{
|
|
#if 0
|
|
gint x;
|
|
gint y;
|
|
gint x0;
|
|
gint y0;
|
|
|
|
gdk_display_get_pointer(gdk_drawable_get_display(window),
|
|
NULL, &x, &y, NULL);
|
|
(void) gdk_window_get_origin(window, &x0, &y0);
|
|
MousePositionNotify(x - x0, y - y0);
|
|
#endif
|
|
gint x;
|
|
gint y;
|
|
|
|
gtk_widget_get_pointer(drawing_area, &x, &y);
|
|
/* (void) gdk_window_get_pointer(window, &x, &y, NULL); */
|
|
MousePositionNotify(x, y);
|
|
}
|
|
|
|
/* --- keyboard input --- */
|
|
|
|
#define MaxNumKeycode 256
|
|
#define KeyCodeMask (MaxNumKeycode - 1)
|
|
/*
|
|
assume keycodes >= 0 and < MaxNumKeycode, which
|
|
isn't promised by gtk documentation.
|
|
*/
|
|
|
|
|
|
LOCALVAR uint8_t KC2MKC[MaxNumKeycode];
|
|
|
|
LOCALPROC KC2MKCAssignOne(guint keyval, uint8_t key)
|
|
{
|
|
GdkKeymapKey *keys;
|
|
gint n_keys;
|
|
int i;
|
|
|
|
if (gdk_keymap_get_entries_for_keyval(NULL,
|
|
keyval, &keys, &n_keys))
|
|
{
|
|
for (i = 0; i < n_keys; i++) {
|
|
KC2MKC[keys[i].keycode & KeyCodeMask] = key;
|
|
}
|
|
g_free(keys);
|
|
}
|
|
#if 0
|
|
fprintf(stderr, "%d %d %d\n", (int)ks, key, (int)code);
|
|
#endif
|
|
}
|
|
|
|
LOCALFUNC bool KC2MKCInit(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 256; ++i) {
|
|
KC2MKC[i] = MKC_None;
|
|
}
|
|
|
|
#ifdef GDK_KP_Insert
|
|
KC2MKCAssignOne(GDK_KP_Insert, MKC_KP0);
|
|
#endif
|
|
#ifdef GDK_KP_End
|
|
KC2MKCAssignOne(GDK_KP_End, MKC_KP1);
|
|
#endif
|
|
#ifdef GDK_KP_Down
|
|
KC2MKCAssignOne(GDK_KP_Down, MKC_KP2);
|
|
#endif
|
|
#ifdef GDK_KP_Next
|
|
KC2MKCAssignOne(GDK_KP_Next, MKC_KP3);
|
|
#endif
|
|
#ifdef GDK_KP_Left
|
|
KC2MKCAssignOne(GDK_KP_Left, MKC_KP4);
|
|
#endif
|
|
#ifdef GDK_KP_Begin
|
|
KC2MKCAssignOne(GDK_KP_Begin, MKC_KP5);
|
|
#endif
|
|
#ifdef GDK_KP_Right
|
|
KC2MKCAssignOne(GDK_KP_Right, MKC_KP6);
|
|
#endif
|
|
#ifdef GDK_KP_Home
|
|
KC2MKCAssignOne(GDK_KP_Home, MKC_KP7);
|
|
#endif
|
|
#ifdef GDK_KP_Up
|
|
KC2MKCAssignOne(GDK_KP_Up, MKC_KP8);
|
|
#endif
|
|
#ifdef GDK_KP_Prior
|
|
KC2MKCAssignOne(GDK_KP_Prior, MKC_KP9);
|
|
#endif
|
|
#ifdef GDK_KP_Delete
|
|
KC2MKCAssignOne(GDK_KP_Delete, MKC_Decimal);
|
|
#endif
|
|
|
|
KC2MKCAssignOne(GDK_asciitilde, MKC_formac_Grave);
|
|
KC2MKCAssignOne(GDK_underscore, MKC_Minus);
|
|
KC2MKCAssignOne(GDK_plus, MKC_Equal);
|
|
KC2MKCAssignOne(GDK_braceleft, MKC_LeftBracket);
|
|
KC2MKCAssignOne(GDK_braceright, MKC_RightBracket);
|
|
KC2MKCAssignOne(GDK_bar, MKC_formac_BackSlash);
|
|
KC2MKCAssignOne(GDK_colon, MKC_SemiColon);
|
|
KC2MKCAssignOne(GDK_quotedbl, MKC_SingleQuote);
|
|
KC2MKCAssignOne(GDK_less, MKC_Comma);
|
|
KC2MKCAssignOne(GDK_greater, MKC_Period);
|
|
KC2MKCAssignOne(GDK_question, MKC_formac_Slash);
|
|
|
|
KC2MKCAssignOne(GDK_a, MKC_A);
|
|
KC2MKCAssignOne(GDK_b, MKC_B);
|
|
KC2MKCAssignOne(GDK_c, MKC_C);
|
|
KC2MKCAssignOne(GDK_d, MKC_D);
|
|
KC2MKCAssignOne(GDK_e, MKC_E);
|
|
KC2MKCAssignOne(GDK_f, MKC_F);
|
|
KC2MKCAssignOne(GDK_g, MKC_G);
|
|
KC2MKCAssignOne(GDK_h, MKC_H);
|
|
KC2MKCAssignOne(GDK_i, MKC_I);
|
|
KC2MKCAssignOne(GDK_j, MKC_J);
|
|
KC2MKCAssignOne(GDK_k, MKC_K);
|
|
KC2MKCAssignOne(GDK_l, MKC_L);
|
|
KC2MKCAssignOne(GDK_m, MKC_M);
|
|
KC2MKCAssignOne(GDK_n, MKC_N);
|
|
KC2MKCAssignOne(GDK_o, MKC_O);
|
|
KC2MKCAssignOne(GDK_p, MKC_P);
|
|
KC2MKCAssignOne(GDK_q, MKC_Q);
|
|
KC2MKCAssignOne(GDK_r, MKC_R);
|
|
KC2MKCAssignOne(GDK_s, MKC_S);
|
|
KC2MKCAssignOne(GDK_t, MKC_T);
|
|
KC2MKCAssignOne(GDK_u, MKC_U);
|
|
KC2MKCAssignOne(GDK_v, MKC_V);
|
|
KC2MKCAssignOne(GDK_w, MKC_W);
|
|
KC2MKCAssignOne(GDK_x, MKC_X);
|
|
KC2MKCAssignOne(GDK_y, MKC_Y);
|
|
KC2MKCAssignOne(GDK_z, MKC_Z);
|
|
|
|
/*
|
|
main mappings
|
|
*/
|
|
|
|
KC2MKCAssignOne(GDK_F1, MKC_formac_F1);
|
|
KC2MKCAssignOne(GDK_F2, MKC_formac_F2);
|
|
KC2MKCAssignOne(GDK_F3, MKC_formac_F3);
|
|
KC2MKCAssignOne(GDK_F4, MKC_formac_F4);
|
|
KC2MKCAssignOne(GDK_F5, MKC_formac_F5);
|
|
KC2MKCAssignOne(GDK_F6, MKC_F6);
|
|
KC2MKCAssignOne(GDK_F7, MKC_F7);
|
|
KC2MKCAssignOne(GDK_F8, MKC_F8);
|
|
KC2MKCAssignOne(GDK_F9, MKC_F9);
|
|
KC2MKCAssignOne(GDK_F10, MKC_F10);
|
|
KC2MKCAssignOne(GDK_F11, MKC_F11);
|
|
KC2MKCAssignOne(GDK_F12, MKC_F12);
|
|
|
|
#ifdef GDK_Delete
|
|
KC2MKCAssignOne(GDK_Delete, MKC_formac_ForwardDel);
|
|
#endif
|
|
#ifdef GDK_Insert
|
|
KC2MKCAssignOne(GDK_Insert, MKC_formac_Help);
|
|
#endif
|
|
#ifdef GDK_Help
|
|
KC2MKCAssignOne(GDK_Help, MKC_formac_Help);
|
|
#endif
|
|
#ifdef GDK_Home
|
|
KC2MKCAssignOne(GDK_Home, MKC_formac_Home);
|
|
#endif
|
|
#ifdef GDK_End
|
|
KC2MKCAssignOne(GDK_End, MKC_formac_End);
|
|
#endif
|
|
|
|
#ifdef GDK_Page_Up
|
|
KC2MKCAssignOne(GDK_Page_Up, MKC_formac_PageUp);
|
|
#else
|
|
#ifdef GDK_Prior
|
|
KC2MKCAssignOne(GDK_Prior, MKC_formac_PageUp);
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef GDK_Page_Down
|
|
KC2MKCAssignOne(GDK_Page_Down, MKC_formac_PageDown);
|
|
#else
|
|
#ifdef GDK_Next
|
|
KC2MKCAssignOne(GDK_Next, MKC_formac_PageDown);
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef GDK_Print
|
|
KC2MKCAssignOne(GDK_Print, MKC_Print);
|
|
#endif
|
|
#ifdef GDK_Scroll_Lock
|
|
KC2MKCAssignOne(GDK_Scroll_Lock, MKC_ScrollLock);
|
|
#endif
|
|
#ifdef GDK_Pause
|
|
KC2MKCAssignOne(GDK_Pause, MKC_Pause);
|
|
#endif
|
|
|
|
KC2MKCAssignOne(GDK_KP_Add, MKC_KPAdd);
|
|
KC2MKCAssignOne(GDK_KP_Subtract, MKC_KPSubtract);
|
|
KC2MKCAssignOne(GDK_KP_Multiply, MKC_KPMultiply);
|
|
KC2MKCAssignOne(GDK_KP_Divide, MKC_KPDevide);
|
|
KC2MKCAssignOne(GDK_KP_Enter, MKC_formac_Enter);
|
|
KC2MKCAssignOne(GDK_KP_Equal, MKC_KPEqual);
|
|
|
|
KC2MKCAssignOne(GDK_KP_0, MKC_KP0);
|
|
KC2MKCAssignOne(GDK_KP_1, MKC_KP1);
|
|
KC2MKCAssignOne(GDK_KP_2, MKC_KP2);
|
|
KC2MKCAssignOne(GDK_KP_3, MKC_KP3);
|
|
KC2MKCAssignOne(GDK_KP_4, MKC_KP4);
|
|
KC2MKCAssignOne(GDK_KP_5, MKC_KP5);
|
|
KC2MKCAssignOne(GDK_KP_6, MKC_KP6);
|
|
KC2MKCAssignOne(GDK_KP_7, MKC_KP7);
|
|
KC2MKCAssignOne(GDK_KP_8, MKC_KP8);
|
|
KC2MKCAssignOne(GDK_KP_9, MKC_KP9);
|
|
KC2MKCAssignOne(GDK_KP_Decimal, MKC_Decimal);
|
|
|
|
KC2MKCAssignOne(GDK_Left, MKC_Left);
|
|
KC2MKCAssignOne(GDK_Right, MKC_Right);
|
|
KC2MKCAssignOne(GDK_Up, MKC_Up);
|
|
KC2MKCAssignOne(GDK_Down, MKC_Down);
|
|
|
|
KC2MKCAssignOne(GDK_grave, MKC_formac_Grave);
|
|
KC2MKCAssignOne(GDK_minus, MKC_Minus);
|
|
KC2MKCAssignOne(GDK_equal, MKC_Equal);
|
|
KC2MKCAssignOne(GDK_bracketleft, MKC_LeftBracket);
|
|
KC2MKCAssignOne(GDK_bracketright, MKC_RightBracket);
|
|
KC2MKCAssignOne(GDK_backslash, MKC_formac_BackSlash);
|
|
KC2MKCAssignOne(GDK_semicolon, MKC_SemiColon);
|
|
KC2MKCAssignOne(GDK_apostrophe, MKC_SingleQuote);
|
|
KC2MKCAssignOne(GDK_comma, MKC_Comma);
|
|
KC2MKCAssignOne(GDK_period, MKC_Period);
|
|
KC2MKCAssignOne(GDK_slash, MKC_formac_Slash);
|
|
|
|
KC2MKCAssignOne(GDK_Escape, MKC_formac_Escape);
|
|
|
|
KC2MKCAssignOne(GDK_Tab, MKC_Tab);
|
|
KC2MKCAssignOne(GDK_Return, MKC_Return);
|
|
KC2MKCAssignOne(GDK_space, MKC_Space);
|
|
KC2MKCAssignOne(GDK_BackSpace, MKC_BackSpace);
|
|
|
|
KC2MKCAssignOne(GDK_Caps_Lock, MKC_formac_CapsLock);
|
|
KC2MKCAssignOne(GDK_Num_Lock, MKC_Clear);
|
|
|
|
KC2MKCAssignOne(GDK_Meta_L, MKC_formac_Command);
|
|
|
|
KC2MKCAssignOne(GDK_Meta_R, MKC_formac_RCommand);
|
|
|
|
KC2MKCAssignOne(GDK_Mode_switch, MKC_formac_Option);
|
|
KC2MKCAssignOne(GDK_Menu, MKC_formac_Option);
|
|
KC2MKCAssignOne(GDK_Super_L, MKC_formac_Option);
|
|
KC2MKCAssignOne(GDK_Super_R, MKC_formac_ROption);
|
|
KC2MKCAssignOne(GDK_Hyper_L, MKC_formac_Option);
|
|
KC2MKCAssignOne(GDK_Hyper_R, MKC_formac_ROption);
|
|
|
|
KC2MKCAssignOne(GDK_F13, MKC_formac_Option);
|
|
/*
|
|
seen being used in Mandrake Linux 9.2
|
|
for windows key
|
|
*/
|
|
|
|
KC2MKCAssignOne(GDK_Shift_L, MKC_formac_Shift);
|
|
KC2MKCAssignOne(GDK_Shift_R, MKC_formac_RShift);
|
|
|
|
KC2MKCAssignOne(GDK_Alt_L, MKC_formac_Command);
|
|
|
|
KC2MKCAssignOne(GDK_Alt_R, MKC_formac_RCommand);
|
|
|
|
KC2MKCAssignOne(GDK_Control_L, MKC_formac_Control);
|
|
|
|
KC2MKCAssignOne(GDK_Control_R, MKC_formac_RControl);
|
|
|
|
KC2MKCAssignOne(GDK_1, MKC_1);
|
|
KC2MKCAssignOne(GDK_2, MKC_2);
|
|
KC2MKCAssignOne(GDK_3, MKC_3);
|
|
KC2MKCAssignOne(GDK_4, MKC_4);
|
|
KC2MKCAssignOne(GDK_5, MKC_5);
|
|
KC2MKCAssignOne(GDK_6, MKC_6);
|
|
KC2MKCAssignOne(GDK_7, MKC_7);
|
|
KC2MKCAssignOne(GDK_8, MKC_8);
|
|
KC2MKCAssignOne(GDK_9, MKC_9);
|
|
KC2MKCAssignOne(GDK_0, MKC_0);
|
|
|
|
KC2MKCAssignOne(GDK_A, MKC_A);
|
|
KC2MKCAssignOne(GDK_B, MKC_B);
|
|
KC2MKCAssignOne(GDK_C, MKC_C);
|
|
KC2MKCAssignOne(GDK_D, MKC_D);
|
|
KC2MKCAssignOne(GDK_E, MKC_E);
|
|
KC2MKCAssignOne(GDK_F, MKC_F);
|
|
KC2MKCAssignOne(GDK_G, MKC_G);
|
|
KC2MKCAssignOne(GDK_H, MKC_H);
|
|
KC2MKCAssignOne(GDK_I, MKC_I);
|
|
KC2MKCAssignOne(GDK_J, MKC_J);
|
|
KC2MKCAssignOne(GDK_K, MKC_K);
|
|
KC2MKCAssignOne(GDK_L, MKC_L);
|
|
KC2MKCAssignOne(GDK_M, MKC_M);
|
|
KC2MKCAssignOne(GDK_N, MKC_N);
|
|
KC2MKCAssignOne(GDK_O, MKC_O);
|
|
KC2MKCAssignOne(GDK_P, MKC_P);
|
|
KC2MKCAssignOne(GDK_Q, MKC_Q);
|
|
KC2MKCAssignOne(GDK_R, MKC_R);
|
|
KC2MKCAssignOne(GDK_S, MKC_S);
|
|
KC2MKCAssignOne(GDK_T, MKC_T);
|
|
KC2MKCAssignOne(GDK_U, MKC_U);
|
|
KC2MKCAssignOne(GDK_V, MKC_V);
|
|
KC2MKCAssignOne(GDK_W, MKC_W);
|
|
KC2MKCAssignOne(GDK_X, MKC_X);
|
|
KC2MKCAssignOne(GDK_Y, MKC_Y);
|
|
KC2MKCAssignOne(GDK_Z, MKC_Z);
|
|
|
|
InitKeyCodes();
|
|
|
|
return true;
|
|
}
|
|
|
|
LOCALPROC CheckTheCapsLock(void)
|
|
{
|
|
GdkModifierType mask;
|
|
|
|
(void) gdk_window_get_pointer(window->window, NULL, NULL, &mask);
|
|
|
|
Keyboard_UpdateKeyMap2(MKC_formac_CapsLock,
|
|
(mask & GDK_LOCK_MASK) != 0);
|
|
}
|
|
|
|
LOCALPROC DoKeyCode(guint keycode, bool down)
|
|
{
|
|
if (GDK_Caps_Lock == keycode) {
|
|
CheckTheCapsLock();
|
|
} else {
|
|
uint8_t key = KC2MKC[keycode & KeyCodeMask];
|
|
|
|
if (MKC_None != key) {
|
|
Keyboard_UpdateKeyMap2(key, down);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* --- time, date, location --- */
|
|
|
|
LOCALVAR uint32_t TrueEmulatedTime = 0;
|
|
|
|
#include "DATE2SEC.h"
|
|
|
|
#define TicksPerSecond 1000000
|
|
|
|
LOCALVAR bool HaveTimeDelta = false;
|
|
LOCALVAR uint32_t TimeDelta;
|
|
|
|
LOCALVAR uint32_t NewMacDateInSeconds;
|
|
|
|
LOCALVAR uint32_t LastTimeSec;
|
|
LOCALVAR uint32_t LastTimeUsec;
|
|
|
|
LOCALPROC GetCurrentTicks(void)
|
|
{
|
|
GTimeVal t;
|
|
|
|
g_get_current_time(&t);
|
|
if (! HaveTimeDelta) {
|
|
time_t Current_Time;
|
|
struct tm *s;
|
|
|
|
#if 0
|
|
GDate *date;
|
|
date = g_date_new();
|
|
g_date_set_time_val(date, &t);
|
|
g_date_free(date);
|
|
#endif
|
|
(void) time(&Current_Time);
|
|
s = localtime(&Current_Time);
|
|
TimeDelta = Date2MacSeconds(s->tm_sec, s->tm_min, s->tm_hour,
|
|
s->tm_mday, 1 + s->tm_mon, 1900 + s->tm_year) - t.tv_sec;
|
|
#if 0 && AutoTimeZone /* how portable is this ? */
|
|
CurMacDelta = ((uint32_t)(s->tm_gmtoff) & 0x00FFFFFF)
|
|
| ((s->tm_isdst ? 0x80 : 0) << 24);
|
|
#endif
|
|
HaveTimeDelta = true;
|
|
}
|
|
|
|
NewMacDateInSeconds = t.tv_sec + TimeDelta;
|
|
LastTimeSec = (uint32_t)t.tv_sec;
|
|
LastTimeUsec = (uint32_t)t.tv_usec;
|
|
}
|
|
|
|
#define InvTimeStep 16626 /* TicksPerSecond / 60.14742 */
|
|
|
|
LOCALVAR uint32_t NextTimeSec;
|
|
LOCALVAR uint32_t NextTimeUsec;
|
|
|
|
LOCALPROC IncrNextTime(void)
|
|
{
|
|
NextTimeUsec += InvTimeStep;
|
|
if (NextTimeUsec >= TicksPerSecond) {
|
|
NextTimeUsec -= TicksPerSecond;
|
|
NextTimeSec += 1;
|
|
}
|
|
}
|
|
|
|
LOCALPROC InitNextTime(void)
|
|
{
|
|
NextTimeSec = LastTimeSec;
|
|
NextTimeUsec = LastTimeUsec;
|
|
IncrNextTime();
|
|
}
|
|
|
|
LOCALPROC StartUpTimeAdjust(void)
|
|
{
|
|
GetCurrentTicks();
|
|
InitNextTime();
|
|
}
|
|
|
|
LOCALFUNC int32_t GetTimeDiff(void)
|
|
{
|
|
return ((int32_t)(LastTimeSec - NextTimeSec)) * TicksPerSecond
|
|
+ ((int32_t)(LastTimeUsec - NextTimeUsec));
|
|
}
|
|
|
|
LOCALPROC UpdateTrueEmulatedTime(void)
|
|
{
|
|
int32_t TimeDiff;
|
|
|
|
GetCurrentTicks();
|
|
|
|
TimeDiff = GetTimeDiff();
|
|
if (TimeDiff >= 0) {
|
|
if (TimeDiff > 4 * InvTimeStep) {
|
|
/* emulation interrupted, forget it */
|
|
++TrueEmulatedTime;
|
|
InitNextTime();
|
|
} else {
|
|
do {
|
|
++TrueEmulatedTime;
|
|
IncrNextTime();
|
|
TimeDiff -= TicksPerSecond;
|
|
} while (TimeDiff >= 0);
|
|
}
|
|
} else if (TimeDiff < - 2 * InvTimeStep) {
|
|
/* clock goofed if ever get here, reset */
|
|
InitNextTime();
|
|
}
|
|
}
|
|
|
|
LOCALFUNC bool CheckDateTime(void)
|
|
{
|
|
if (CurMacDateInSeconds != NewMacDateInSeconds) {
|
|
CurMacDateInSeconds = NewMacDateInSeconds;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
LOCALFUNC bool InitLocationDat(void)
|
|
{
|
|
GetCurrentTicks();
|
|
CurMacDateInSeconds = NewMacDateInSeconds;
|
|
|
|
return true;
|
|
}
|
|
|
|
/* --- basic dialogs --- */
|
|
|
|
LOCALPROC CheckSavedMacMsg(void)
|
|
{
|
|
if (nullpr != SavedBriefMsg) {
|
|
char briefMsg0[ClStrMaxLength + 1];
|
|
char longMsg0[ClStrMaxLength + 1];
|
|
|
|
NativeStrFromCStr(briefMsg0, SavedBriefMsg, false);
|
|
NativeStrFromCStr(longMsg0, SavedLongMsg, false);
|
|
|
|
fprintf(stderr, "%s\n", briefMsg0);
|
|
fprintf(stderr, "%s\n", longMsg0);
|
|
|
|
SavedBriefMsg = nullpr;
|
|
}
|
|
}
|
|
|
|
LOCALVAR bool CaughtMouse = false;
|
|
|
|
/* --- main window creation and disposal --- */
|
|
|
|
LOCALVAR int argc;
|
|
LOCALVAR char **argv;
|
|
|
|
/* Create a new backing pixmap of the appropriate size */
|
|
static gboolean configure_event(GtkWidget *widget,
|
|
GdkEventConfigure *event)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
/* Redraw the screen from the backing pixmap */
|
|
static gboolean expose_event(GtkWidget *widget,
|
|
GdkEventExpose *event,
|
|
gpointer user_data)
|
|
{
|
|
int x0 = event->area.x;
|
|
int y0 = event->area.y;
|
|
int x1 = x0 + event->area.width;
|
|
int y1 = y0 + event->area.height;
|
|
|
|
#if 0 && DbgEvents
|
|
fprintf(stderr, "- event - Expose\n");
|
|
#endif
|
|
|
|
if (x0 < 0) {
|
|
x0 = 0;
|
|
}
|
|
if (x1 > vMacScreenWidth) {
|
|
x1 = vMacScreenWidth;
|
|
}
|
|
if (y0 < 0) {
|
|
y0 = 0;
|
|
}
|
|
if (y1 > vMacScreenHeight) {
|
|
y1 = vMacScreenHeight;
|
|
}
|
|
if ((x0 < x1) && (y0 < y1)) {
|
|
HaveChangedScreenBuff(y0, x0, y1, x1);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean button_press_event(GtkWidget *widget,
|
|
GdkEventButton *event,
|
|
gpointer user_data)
|
|
{
|
|
MousePositionNotify(event->x, event->y);
|
|
MouseButtonSet(true);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean button_release_event(GtkWidget *widget,
|
|
GdkEventButton *event,
|
|
gpointer user_data)
|
|
{
|
|
MousePositionNotify(event->x, event->y);
|
|
MouseButtonSet(false);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean motion_notify_event(GtkWidget *widget,
|
|
GdkEventMotion *event,
|
|
gpointer user_data)
|
|
{
|
|
int x;
|
|
int y;
|
|
GdkModifierType state;
|
|
|
|
if (event->is_hint) {
|
|
gdk_window_get_pointer(event->window, &x, &y, &state);
|
|
} else {
|
|
x = event->x;
|
|
y = event->y;
|
|
state = event->state;
|
|
}
|
|
|
|
MousePositionNotify(x, y);
|
|
MouseButtonSet((state & GDK_BUTTON1_MASK) != 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean enter_notify_event(GtkWidget *widget,
|
|
GdkEventCrossing *event,
|
|
gpointer user_data)
|
|
{
|
|
CaughtMouse = true;
|
|
|
|
MousePositionNotify(event->x, event->y);
|
|
MouseButtonSet((event->state & GDK_BUTTON1_MASK) != 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean leave_notify_event(GtkWidget *widget,
|
|
GdkEventCrossing *event,
|
|
gpointer user_data)
|
|
{
|
|
MousePositionNotify(event->x, event->y);
|
|
MouseButtonSet((event->state & GDK_BUTTON1_MASK) != 0);
|
|
|
|
CaughtMouse = false;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean delete_event(GtkWidget *widget,
|
|
GdkEventMotion *event)
|
|
{
|
|
RequestMacOff = true;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LOCALPROC ReconnectKeyCodes3(void)
|
|
{
|
|
CheckTheCapsLock();
|
|
|
|
#if 0
|
|
if (WantCmdOptOnReconnect) {
|
|
WantCmdOptOnReconnect = false;
|
|
|
|
GetTheDownKeys();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
LOCALPROC DisconnectKeyCodes3(void)
|
|
{
|
|
DisconnectKeyCodes2();
|
|
MouseButtonSet(false);
|
|
}
|
|
|
|
LOCALVAR bool ADialogIsUp = false;
|
|
|
|
LOCALPROC BeginDialog(void)
|
|
{
|
|
DisconnectKeyCodes3();
|
|
ADialogIsUp = true;
|
|
ForceShowCursor();
|
|
}
|
|
|
|
LOCALPROC EndDialog(void)
|
|
{
|
|
ADialogIsUp = false;
|
|
ReconnectKeyCodes3();
|
|
}
|
|
|
|
/* --- SavedTasks --- */
|
|
|
|
LOCALPROC LeaveBackground(void)
|
|
{
|
|
ReconnectKeyCodes3();
|
|
#if 0
|
|
DisableKeyRepeat();
|
|
#endif
|
|
}
|
|
|
|
LOCALPROC EnterBackground(void)
|
|
{
|
|
#if 0
|
|
RestoreKeyRepeat();
|
|
#endif
|
|
DisconnectKeyCodes3();
|
|
|
|
ForceShowCursor();
|
|
}
|
|
|
|
LOCALPROC LeaveSpeedStopped(void)
|
|
{
|
|
StartUpTimeAdjust();
|
|
}
|
|
|
|
LOCALPROC EnterSpeedStopped(void)
|
|
{
|
|
}
|
|
|
|
static void InsertADisk0(void)
|
|
{
|
|
char ts[ClStrMaxLength + 1];
|
|
GtkWidget *dialog;
|
|
|
|
NativeStrFromCStr(ts, kStrMenuItemOpen, false);
|
|
|
|
BeginDialog();
|
|
dialog = gtk_file_chooser_dialog_new(ts,
|
|
GTK_WINDOW(window),
|
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
|
NULL);
|
|
EndDialog();
|
|
|
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
|
char *filename;
|
|
|
|
filename =
|
|
gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
|
(void) Sony_Insert1a(filename, false);
|
|
g_free(filename);
|
|
}
|
|
|
|
gtk_widget_destroy(dialog);
|
|
}
|
|
|
|
LOCALPROC CheckForSavedTasks(void)
|
|
{
|
|
if (EvtQNeedRecover) {
|
|
EvtQNeedRecover = false;
|
|
|
|
/* attempt cleanup, EvtQNeedRecover may get set again */
|
|
EvtQTryRecoverFromFull();
|
|
}
|
|
|
|
if (RequestMacOff) {
|
|
RequestMacOff = false;
|
|
if (AnyDiskInserted()) {
|
|
MacMsgOverride(kStrQuitWarningTitle,
|
|
kStrQuitWarningMessage);
|
|
} else {
|
|
ForceMacOff = true;
|
|
}
|
|
}
|
|
|
|
if (ForceMacOff) {
|
|
return;
|
|
}
|
|
|
|
if (gTrueBackgroundFlag != gBackgroundFlag) {
|
|
gBackgroundFlag = gTrueBackgroundFlag;
|
|
if (gTrueBackgroundFlag) {
|
|
EnterBackground();
|
|
} else {
|
|
LeaveBackground();
|
|
}
|
|
}
|
|
|
|
if (CurSpeedStopped != (SpeedStopped ||
|
|
(gBackgroundFlag && ! RunInBackground
|
|
#if EnableAutoSlow && 0
|
|
&& (QuietSubTicks >= 4092)
|
|
#endif
|
|
)))
|
|
{
|
|
CurSpeedStopped = ! CurSpeedStopped;
|
|
if (CurSpeedStopped) {
|
|
EnterSpeedStopped();
|
|
} else {
|
|
LeaveSpeedStopped();
|
|
}
|
|
}
|
|
|
|
|
|
if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
|
|
MacMsgDisplayOn();
|
|
}
|
|
|
|
if (NeedWholeScreenDraw) {
|
|
NeedWholeScreenDraw = false;
|
|
ScreenChangedAll();
|
|
}
|
|
|
|
if (HaveCursorHidden != (WantCursorHidden && CaughtMouse
|
|
&& ! (gTrueBackgroundFlag || ADialogIsUp || CurSpeedStopped)))
|
|
{
|
|
HaveCursorHidden = ! HaveCursorHidden;
|
|
if (HaveCursorHidden) {
|
|
gdk_window_set_cursor(window->window, blank_cursor);
|
|
} else {
|
|
gdk_window_set_cursor(window->window, NULL);
|
|
}
|
|
}
|
|
|
|
if (gTrueBackgroundFlag || ADialogIsUp) {
|
|
} else {
|
|
if (RequestInsertDisk) {
|
|
RequestInsertDisk = false;
|
|
InsertADisk0();
|
|
}
|
|
}
|
|
|
|
#if NeedRequestIthDisk
|
|
if (0 != RequestIthDisk) {
|
|
Sony_InsertIth(RequestIthDisk);
|
|
RequestIthDisk = 0;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* --- command line parsing --- */
|
|
|
|
LOCALFUNC bool ScanCommandLine(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 1; i < argc; ++i) {
|
|
if ('-' == argv[i][0]) {
|
|
#if 0
|
|
if ((0 == strcmp(argv[i], "--display")) ||
|
|
(0 == strcmp(argv[i], "-display")))
|
|
{
|
|
++i;
|
|
if (i < argc) {
|
|
display_name = argv[i];
|
|
}
|
|
} else
|
|
#endif
|
|
if ((0 == strcmp(argv[i], "--rom")) ||
|
|
(0 == strcmp(argv[i], "-r")))
|
|
{
|
|
++i;
|
|
if (i < argc) {
|
|
rom_path = argv[i];
|
|
}
|
|
} else
|
|
#if 0
|
|
if (0 == strcmp(argv[i], "-l")) {
|
|
SpeedValue = 0;
|
|
} else
|
|
#endif
|
|
{
|
|
MacMsg(kStrBadArgTitle, kStrBadArgMessage, false);
|
|
}
|
|
} else {
|
|
(void) Sony_Insert1(argv[i], false);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/* --- main program flow --- */
|
|
|
|
GLOBALOSGLUFUNC bool ExtraTimeNotOver(void)
|
|
{
|
|
UpdateTrueEmulatedTime();
|
|
return TrueEmulatedTime == OnTrueTime;
|
|
}
|
|
|
|
LOCALPROC WaitForTheNextEvent(void)
|
|
{
|
|
(void) gtk_main_iteration_do(TRUE);
|
|
}
|
|
|
|
LOCALPROC CheckForSystemEvents(void)
|
|
{
|
|
int i = 10;
|
|
|
|
while (gtk_events_pending() && (--i >= 0)) {
|
|
(void) gtk_main_iteration_do(FALSE);
|
|
}
|
|
#if 0
|
|
XFlush(x_display);
|
|
#endif
|
|
}
|
|
|
|
GLOBALOSGLUPROC WaitForNextTick(void)
|
|
{
|
|
label_retry:
|
|
CheckForSystemEvents();
|
|
CheckForSavedTasks();
|
|
if (ForceMacOff) {
|
|
return;
|
|
}
|
|
|
|
if (CurSpeedStopped) {
|
|
DoneWithDrawingForTick();
|
|
WaitForTheNextEvent();
|
|
goto label_retry;
|
|
}
|
|
|
|
if (ExtraTimeNotOver()) {
|
|
int32_t TimeDiff = GetTimeDiff();
|
|
if (TimeDiff < 0) {
|
|
g_usleep(- TimeDiff);
|
|
}
|
|
goto label_retry;
|
|
}
|
|
|
|
if (CheckDateTime()) {
|
|
}
|
|
|
|
if ((! gBackgroundFlag || ADialogIsUp)
|
|
&& (! CaughtMouse)
|
|
)
|
|
{
|
|
CheckMouseState();
|
|
}
|
|
|
|
OnTrueTime = TrueEmulatedTime;
|
|
}
|
|
|
|
#include "PROGMAIN.h"
|
|
|
|
static gboolean
|
|
MainEventLoop0(gpointer data)
|
|
{
|
|
(void) data;
|
|
fprintf(stderr, "hello from MainEventLoop0\n");
|
|
ProgramMain();
|
|
if (ForceMacOff) {
|
|
goto Label_01;
|
|
}
|
|
#if 0
|
|
while (! gtk_main_iteration_do(FALSE)) {
|
|
if (! gtk_events_pending()) {
|
|
fprintf(stderr, "sleep\n");
|
|
g_usleep(1000000);
|
|
}
|
|
}
|
|
#endif
|
|
Label_01:
|
|
fprintf(stderr, "leaving MainEventLoop0\n");
|
|
|
|
gtk_main_quit();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
focus_in_event(GtkWidget *widget, GdkEvent *event,
|
|
gpointer data)
|
|
{
|
|
gTrueBackgroundFlag = false;
|
|
|
|
CheckMouseState();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
focus_out_event(GtkWidget *widget, GdkEvent *event,
|
|
gpointer data)
|
|
{
|
|
gTrueBackgroundFlag = true;
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean key_press_event(GtkWidget *widget,
|
|
GdkEventKey *event,
|
|
gpointer user_data)
|
|
{
|
|
#if 0
|
|
fprintf(stderr, "hello from key_press_event\n");
|
|
fprintf(stderr, "keyval %d\n", event->keyval);
|
|
fprintf(stderr, "hardware_keycode %d\n", event->hardware_keycode);
|
|
#endif
|
|
#if 0
|
|
{
|
|
GdkKeymapKey *keys;
|
|
gint n_keys;
|
|
int i;
|
|
|
|
if (gdk_keymap_get_entries_for_keyval(NULL,
|
|
event->keyval, &keys, &n_keys))
|
|
{
|
|
for (i = 0; i < n_keys; i++) {
|
|
fprintf(stderr, "keycode %d\n", keys[i].keycode);
|
|
}
|
|
g_free(keys);
|
|
}
|
|
}
|
|
#endif
|
|
DoKeyCode(event->hardware_keycode, true);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean key_release_event(GtkWidget *widget,
|
|
GdkEventKey *event,
|
|
gpointer user_data)
|
|
{
|
|
#if 0
|
|
fprintf(stderr, "hello from key_release_event\n");
|
|
fprintf(stderr, "keyval %d\n", event->keyval);
|
|
fprintf(stderr, "hardware_keycode %d\n", event->hardware_keycode);
|
|
#endif
|
|
DoKeyCode(event->hardware_keycode, false);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void drag_data_received(GtkWidget *widget,
|
|
GdkDragContext *drag_context,
|
|
gint x,
|
|
gint y,
|
|
GtkSelectionData *data,
|
|
guint info,
|
|
guint time,
|
|
gpointer user_data)
|
|
{
|
|
char **uris;
|
|
char *file;
|
|
int i;
|
|
gboolean handled = FALSE;
|
|
|
|
uris = g_strsplit((char *)data->data, "\r\n", -1);
|
|
if (uris != NULL) {
|
|
for (i = 0; uris[i] != NULL; i++) {
|
|
file = g_filename_from_uri(uris[i], NULL, NULL);
|
|
/* file = gnome_vfs_get_local_path_from_uri(uris[i]); */
|
|
if (file != NULL) {
|
|
(void) Sony_Insert1a(file, false);
|
|
handled = TRUE;
|
|
g_free(file);
|
|
}
|
|
}
|
|
g_strfreev(uris);
|
|
}
|
|
gtk_drag_finish(drag_context, handled, FALSE, time);
|
|
if (handled) {
|
|
gtk_window_present_with_time(GTK_WINDOW(window), time);
|
|
}
|
|
}
|
|
|
|
static void do_more_commands_item(GtkAction *action, gpointer user_data)
|
|
{
|
|
DoMoreCommandsMsg();
|
|
}
|
|
|
|
static void do_about_item(GtkAction *action, gpointer user_data)
|
|
{
|
|
DoAboutMsg();
|
|
}
|
|
|
|
static void do_quit_item(GtkAction *action, gpointer user_data)
|
|
{
|
|
RequestMacOff = true;
|
|
}
|
|
|
|
static void do_open_item(GtkAction *action, gpointer user_data)
|
|
{
|
|
RequestInsertDisk = true;
|
|
}
|
|
|
|
LOCALPROC AppendConvertMenuItem(GtkWidget *the_menu,
|
|
GCallback c_handler, gpointer gobject, char *s, bool AddEllipsis)
|
|
{
|
|
char ts[ClStrMaxLength + 1];
|
|
GtkWidget *the_item;
|
|
|
|
NativeStrFromCStr(ts, s, AddEllipsis);
|
|
the_item = gtk_menu_item_new_with_label(ts);
|
|
g_signal_connect(G_OBJECT(the_item), "activate",
|
|
c_handler, gobject);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(the_menu), the_item);
|
|
}
|
|
|
|
LOCALPROC AppendSubmenuConvertName(GtkWidget *menubar,
|
|
GtkWidget *the_menu, char *s)
|
|
{
|
|
char ts[ClStrMaxLength + 1];
|
|
GtkWidget *the_item;
|
|
|
|
NativeStrFromCStr(ts, s, false);
|
|
the_item = gtk_menu_item_new_with_label(ts);
|
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(the_item), the_menu);
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), the_item);
|
|
}
|
|
|
|
static GdkPixmap *blank_pixmap;
|
|
static GdkColor blank_color = {
|
|
0, 0, 0, 0
|
|
};
|
|
|
|
static gchar blank_cursor_bits[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
static GtkTargetEntry dnd_target =
|
|
{
|
|
"text/uri-list", 0, 0
|
|
};
|
|
|
|
LOCALPROC ZapOSGLUVars(void)
|
|
{
|
|
InitDrives();
|
|
#if 0
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < kNumMagStates; ++i) {
|
|
HavePositionWins[i] = false;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
LOCALPROC ReserveAllocAll(void)
|
|
{
|
|
#if dbglog_HAVE
|
|
dbglog_ReserveAlloc();
|
|
#endif
|
|
ReserveAllocOneBlock(&ROM, kROM_Size, 5, false);
|
|
ReserveAllocOneBlock(&screencomparebuff,
|
|
vMacScreenNumBytes, 5, true);
|
|
#if UseControlKeys
|
|
ReserveAllocOneBlock(&CntrlDisplayBuff,
|
|
vMacScreenNumBytes, 5, false);
|
|
#endif
|
|
|
|
EmulationReserveAlloc();
|
|
}
|
|
|
|
LOCALFUNC bool AllocMemory(void)
|
|
{
|
|
uimr n;
|
|
bool IsOk = false;
|
|
|
|
ReserveAllocOffset = 0;
|
|
ReserveAllocBigBlock = nullpr;
|
|
ReserveAllocAll();
|
|
n = ReserveAllocOffset;
|
|
ReserveAllocBigBlock = (uint8_t *)calloc(1, n);
|
|
if (NULL == ReserveAllocBigBlock) {
|
|
MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, true);
|
|
} else {
|
|
ReserveAllocOffset = 0;
|
|
ReserveAllocAll();
|
|
if (n != ReserveAllocOffset) {
|
|
/* oops, program error */
|
|
} else {
|
|
IsOk = true;
|
|
}
|
|
}
|
|
|
|
return IsOk;
|
|
}
|
|
|
|
LOCALPROC UnallocMemory(void)
|
|
{
|
|
if (nullpr != ReserveAllocBigBlock) {
|
|
free((char *)ReserveAllocBigBlock);
|
|
}
|
|
}
|
|
|
|
LOCALFUNC bool InitOSGLU(void)
|
|
{
|
|
if (AllocMemory())
|
|
#if dbglog_HAVE
|
|
if (dbglog_open())
|
|
#endif
|
|
if (ScanCommandLine())
|
|
if (LoadMacRom())
|
|
if (LoadInitialImages())
|
|
if (InitLocationDat())
|
|
/* if (ReCreateMainWindow()) */
|
|
if (KC2MKCInit())
|
|
if (WaitForRom())
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
LOCALPROC UnInitOSGLU(void)
|
|
{
|
|
if (MacMsgDisplayed) {
|
|
MacMsgDisplayOff();
|
|
}
|
|
|
|
UnInitDrives();
|
|
|
|
ForceShowCursor();
|
|
|
|
#if dbglog_HAVE
|
|
dbglog_close();
|
|
#endif
|
|
|
|
UnallocMemory();
|
|
|
|
CheckSavedMacMsg();
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
GtkWidget *vbox;
|
|
|
|
#if 0
|
|
GtkWidget *button;
|
|
#endif
|
|
|
|
GtkWidget *menubar;
|
|
GtkWidget *the_menu;
|
|
GtkWidget *the_item;
|
|
|
|
gtk_init(&argc, &argv);
|
|
|
|
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
|
gtk_widget_set_name(window, "Test Input");
|
|
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
|
|
|
|
vbox = gtk_vbox_new(FALSE, 0);
|
|
gtk_container_add(GTK_CONTAINER(window), vbox);
|
|
gtk_widget_show(vbox);
|
|
|
|
g_signal_connect(G_OBJECT(window), "delete-event",
|
|
G_CALLBACK(delete_event), NULL);
|
|
g_signal_connect(G_OBJECT(window), "focus-out-event",
|
|
(GCallback)focus_out_event,
|
|
NULL);
|
|
g_signal_connect(G_OBJECT(window), "focus-in-event",
|
|
(GCallback)focus_in_event, NULL);
|
|
|
|
g_signal_connect(G_OBJECT(window), "key-press-event",
|
|
G_CALLBACK(key_press_event), NULL);
|
|
g_signal_connect(G_OBJECT(window), "key-release-event",
|
|
G_CALLBACK(key_release_event), NULL);
|
|
|
|
menubar = gtk_menu_bar_new();
|
|
|
|
the_menu = gtk_menu_new();
|
|
|
|
AppendConvertMenuItem(the_menu,
|
|
G_CALLBACK(do_open_item), NULL, kStrMenuItemOpen, true);
|
|
|
|
the_item = gtk_separator_menu_item_new();
|
|
gtk_menu_shell_append(GTK_MENU_SHELL(the_menu), the_item);
|
|
|
|
AppendConvertMenuItem(the_menu,
|
|
G_CALLBACK(do_quit_item), NULL, kStrMenuItemQuit, false);
|
|
|
|
AppendSubmenuConvertName(menubar, the_menu, kStrMenuFile);
|
|
|
|
the_menu = gtk_menu_new();
|
|
|
|
AppendConvertMenuItem(the_menu, G_CALLBACK(do_more_commands_item),
|
|
NULL, kStrMenuItemMore, true);
|
|
|
|
AppendSubmenuConvertName(menubar, the_menu, kStrMenuSpecial);
|
|
|
|
the_menu = gtk_menu_new();
|
|
|
|
AppendConvertMenuItem(the_menu,
|
|
G_CALLBACK(do_about_item), NULL, kStrMenuItemAbout, true);
|
|
|
|
AppendSubmenuConvertName(menubar, the_menu, kStrMenuHelp);
|
|
|
|
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show_all(menubar);
|
|
|
|
|
|
/* Create the drawing area */
|
|
|
|
drawing_area = gtk_drawing_area_new();
|
|
gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
|
|
vMacScreenWidth, vMacScreenHeight);
|
|
gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show(drawing_area);
|
|
|
|
/* Signals used to handle backing pixmap */
|
|
|
|
g_signal_connect(G_OBJECT(drawing_area), "expose-event",
|
|
G_CALLBACK(expose_event), NULL);
|
|
g_signal_connect(G_OBJECT(drawing_area), "configure-event",
|
|
G_CALLBACK(configure_event), NULL);
|
|
|
|
/* Event signals */
|
|
|
|
g_signal_connect(G_OBJECT(drawing_area), "motion-notify-event",
|
|
G_CALLBACK(motion_notify_event), NULL);
|
|
g_signal_connect(G_OBJECT(drawing_area), "enter-notify-event",
|
|
G_CALLBACK(enter_notify_event), NULL);
|
|
g_signal_connect(G_OBJECT(drawing_area), "leave-notify-event",
|
|
G_CALLBACK(leave_notify_event), NULL);
|
|
|
|
g_signal_connect(G_OBJECT(drawing_area), "button-press-event",
|
|
G_CALLBACK(button_press_event), NULL);
|
|
g_signal_connect(G_OBJECT(drawing_area), "button-release-event",
|
|
G_CALLBACK(button_release_event), NULL);
|
|
|
|
gtk_widget_add_events(window,
|
|
GDK_KEY_PRESS_MASK
|
|
| GDK_KEY_RELEASE_MASK
|
|
);
|
|
|
|
gtk_widget_set_events(drawing_area, GDK_EXPOSURE_MASK
|
|
| GDK_LEAVE_NOTIFY_MASK
|
|
| GDK_BUTTON_PRESS_MASK
|
|
| GDK_BUTTON_RELEASE_MASK
|
|
| GDK_POINTER_MOTION_MASK
|
|
| GDK_ENTER_NOTIFY_MASK
|
|
| GDK_LEAVE_NOTIFY_MASK
|
|
| GDK_FOCUS_CHANGE_MASK
|
|
| GDK_KEY_PRESS_MASK
|
|
| GDK_KEY_RELEASE_MASK
|
|
/* | GDK_POINTER_MOTION_HINT_MASK */
|
|
);
|
|
|
|
#if 0
|
|
/* .. And a quit button */
|
|
button = gtk_button_new_with_label("Quit");
|
|
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
|
|
|
|
g_signal_connect_swapped(G_OBJECT(button), "clicked",
|
|
G_CALLBACK(delete_event), NULL
|
|
/*
|
|
G_CALLBACK(gtk_widget_destroy),
|
|
G_OBJECT(window)
|
|
*/
|
|
);
|
|
gtk_widget_show(button);
|
|
#endif
|
|
|
|
gtk_drag_dest_set(drawing_area, GTK_DEST_DEFAULT_ALL,
|
|
&dnd_target, 1,
|
|
GDK_ACTION_COPY);
|
|
g_signal_connect(GTK_OBJECT(drawing_area), "drag-data-received",
|
|
G_CALLBACK(drag_data_received), NULL);
|
|
|
|
gtk_widget_show(window);
|
|
|
|
blank_pixmap = gdk_bitmap_create_from_data(NULL,
|
|
blank_cursor_bits, 16, 16);
|
|
blank_cursor = gdk_cursor_new_from_pixmap(blank_pixmap,
|
|
blank_pixmap, &blank_color, &blank_color, 8, 8);
|
|
gdk_pixmap_unref(blank_pixmap);
|
|
|
|
gdk_window_set_cursor(window->window, blank_cursor);
|
|
|
|
g_idle_add(MainEventLoop0, NULL);
|
|
|
|
argc = argc;
|
|
argv = argv;
|
|
|
|
ZapOSGLUVars();
|
|
if (InitOSGLU()) {
|
|
gtk_main ();
|
|
}
|
|
UnInitOSGLU();
|
|
|
|
return 0;
|
|
}
|