this repo has no description
1/*
2 OSGLUGTK.c
3
4 Copyright (C) 2009 Paul C. Pratt
5
6 You can redistribute this file and/or modify it under the terms
7 of version 2 of the GNU General Public License as published by
8 the Free Software Foundation. You should have received a copy
9 of the license along with this file; see the file COPYING.
10
11 This file is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 license for more details.
15*/
16
17/*
18 Operating System GLUe for GTK
19
20 All operating system dependent code for the
21 GIMP Toolkit should go here.
22*/
23
24#include "OSGCOMUI.h"
25#include "OSGCOMUD.h"
26
27#ifdef WantOSGLUGTK
28
29#include "COMOSGLU.h"
30
31/* --- some simple utilities --- */
32
33GLOBALOSGLUPROC MyMoveBytes(anyp srcPtr, anyp destPtr, si5b byteCount)
34{
35 (void) memcpy((char *)destPtr, (char *)srcPtr, byteCount);
36}
37
38/* --- control mode and internationalization --- */
39
40#define NeedCell2PlainAsciiMap 1
41#define NeedRequestInsertDisk 1
42#define NeedDoMoreCommandsMsg 1
43#define NeedDoAboutMsg 1
44
45#include "INTLCHAR.h"
46
47#include "CONTROLM.h"
48
49/* --- sending debugging info to file --- */
50
51#if dbglog_HAVE
52
53#define dbglog_ToStdErr 0
54
55#if ! dbglog_ToStdErr
56LOCALVAR FILE *dbglog_File = NULL;
57#endif
58
59LOCALFUNC blnr dbglog_open0(void)
60{
61#if dbglog_ToStdErr
62 return trueblnr;
63#else
64 dbglog_File = fopen("dbglog.txt", "w");
65 return (NULL != dbglog_File);
66#endif
67}
68
69LOCALPROC dbglog_write0(char *s, uimr L)
70{
71#if dbglog_ToStdErr
72 (void) fwrite(s, 1, L, stderr);
73#else
74 if (dbglog_File != NULL) {
75 (void) fwrite(s, 1, L, dbglog_File);
76 }
77#endif
78}
79
80LOCALPROC dbglog_close0(void)
81{
82#if ! dbglog_ToStdErr
83 if (dbglog_File != NULL) {
84 fclose(dbglog_File);
85 dbglog_File = NULL;
86 }
87#endif
88}
89
90#endif
91
92/* --- debug settings and utilities --- */
93
94#define MyDbgEvents (dbglog_HAVE && 1)
95
96#if ! dbglog_HAVE
97#define WriteExtraErr(s)
98#else
99LOCALPROC WriteExtraErr(char *s)
100{
101 dbglog_writeCStr("*** error: ");
102 dbglog_writeCStr(s);
103 dbglog_writeReturn();
104}
105#endif
106
107/* --- text translation --- */
108
109LOCALPROC NativeStrFromCStr(char *r, char *s, blnr AddEllipsis)
110{
111 ui3b ps[ClStrMaxLength];
112 int i;
113 int L;
114
115 ClStrFromSubstCStr(&L, ps, s);
116
117 for (i = 0; i < L; ++i) {
118 r[i] = Cell2PlainAsciiMap[ps[i]];
119 }
120
121 if (AddEllipsis) {
122 r[L] = '.';
123 ++L;
124 r[L] = '.';
125 ++L;
126 r[L] = '.';
127 ++L;
128 }
129
130 r[L] = 0;
131}
132
133/* --- drives --- */
134
135#define NotAfileRef NULL
136
137LOCALVAR FILE *Drives[NumDrives]; /* open disk image files */
138
139LOCALPROC InitDrives(void)
140{
141 /*
142 This isn't really needed, Drives[i] and DriveNames[i]
143 need not have valid values when not vSonyIsInserted[i].
144 */
145 tDrive i;
146
147 for (i = 0; i < NumDrives; ++i) {
148 Drives[i] = NotAfileRef;
149 }
150}
151
152GLOBALOSGLUFUNC tMacErr vSonyTransfer(blnr IsWrite, ui3p Buffer,
153 tDrive Drive_No, ui5r Sony_Start, ui5r Sony_Count,
154 ui5r *Sony_ActCount)
155{
156 ui5r NewSony_Count = Sony_Count;
157
158 fseek(Drives[Drive_No], Sony_Start, SEEK_SET);
159
160 if (IsWrite) {
161 fwrite(Buffer, 1, NewSony_Count, Drives[Drive_No]);
162 } else {
163 fread(Buffer, 1, NewSony_Count, Drives[Drive_No]);
164 }
165
166 if (nullpr != Sony_ActCount) {
167 *Sony_ActCount = NewSony_Count;
168 }
169
170 return mnvm_noErr; /*& figure out what really to return &*/
171}
172
173GLOBALOSGLUFUNC tMacErr vSonyGetSize(tDrive Drive_No, ui5r *Sony_Count)
174{
175 fseek(Drives[Drive_No], 0, SEEK_END);
176 *Sony_Count = ftell(Drives[Drive_No]);
177 return mnvm_noErr; /*& figure out what really to return &*/
178}
179
180LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit)
181{
182 DiskEjectedNotify(Drive_No);
183
184 fclose(Drives[Drive_No]);
185 Drives[Drive_No] = NotAfileRef; /* not really needed */
186
187
188 return mnvm_noErr;
189}
190
191GLOBALOSGLUFUNC tMacErr vSonyEject(tDrive Drive_No)
192{
193 return vSonyEject0(Drive_No, falseblnr);
194}
195
196LOCALPROC UnInitDrives(void)
197{
198 tDrive i;
199
200 for (i = 0; i < NumDrives; ++i) {
201 if (vSonyIsInserted(i)) {
202 (void) vSonyEject(i);
203 }
204 }
205}
206
207LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked,
208 char *drivepath)
209{
210 tDrive Drive_No;
211
212 if (! FirstFreeDisk(&Drive_No)) {
213 fclose(refnum);
214 MacMsg(kStrTooManyImagesTitle,
215 kStrTooManyImagesMessage, falseblnr);
216 return falseblnr;
217 } else {
218 /* printf("Sony_Insert0 %d\n", (int)Drive_No); */
219 Drives[Drive_No] = refnum;
220 DiskInsertNotify(Drive_No, locked);
221
222 return trueblnr;
223 }
224}
225
226LOCALFUNC blnr Sony_Insert1(char *drivepath, blnr silentfail)
227{
228 blnr locked = falseblnr;
229 /* printf("Sony_Insert1 %s\n", drivepath); */
230 FILE *refnum = fopen(drivepath, "rb+");
231 if (NULL == refnum) {
232 locked = trueblnr;
233 refnum = fopen(drivepath, "rb");
234 }
235 if (NULL == refnum) {
236 if (! silentfail) {
237 MacMsg(kStrOpenFailTitle, kStrOpenFailMessage, falseblnr);
238 }
239 } else {
240 return Sony_Insert0(refnum, locked, drivepath);
241 }
242 return falseblnr;
243}
244
245LOCALFUNC tMacErr LoadMacRomFrom(char *path)
246{
247 tMacErr err;
248 FILE *ROM_File;
249 int File_Size;
250
251 ROM_File = fopen(path, "rb");
252 if (NULL == ROM_File) {
253 err = mnvm_fnfErr;
254 } else {
255 File_Size = fread(ROM, 1, kROM_Size, ROM_File);
256 if (kROM_Size != File_Size) {
257 if (feof(ROM_File)) {
258 MacMsgOverride(kStrShortROMTitle,
259 kStrShortROMMessage);
260 err = mnvm_eofErr;
261 } else {
262 MacMsgOverride(kStrNoReadROMTitle,
263 kStrNoReadROMMessage);
264 err = mnvm_miscErr;
265 }
266 } else {
267 err = ROM_IsValid();
268 }
269 fclose(ROM_File);
270 }
271
272 return err;
273}
274
275LOCALFUNC blnr Sony_Insert1a(char *drivepath, blnr silentfail)
276{
277 blnr v;
278
279 if (! ROM_loaded) {
280 v = (mnvm_noErr == LoadMacRomFrom(drivepath));
281 } else {
282 v = Sony_Insert1(drivepath, silentfail);
283 }
284
285 return v;
286}
287
288LOCALFUNC blnr Sony_InsertIth(int i)
289{
290 blnr v;
291
292 if ((i > 9) || ! FirstFreeDisk(nullpr)) {
293 v = falseblnr;
294 } else {
295 char s[] = "disk?.dsk";
296
297 s[4] = '0' + i;
298
299 v = Sony_Insert1(s, trueblnr);
300 }
301
302 return v;
303}
304
305LOCALFUNC blnr LoadInitialImages(void)
306{
307 int i;
308
309 for (i = 1; Sony_InsertIth(i); ++i) {
310 /* stop on first error (including file not found) */
311 }
312
313 return trueblnr;
314}
315
316/* --- ROM --- */
317
318LOCALVAR char *rom_path = NULL;
319
320LOCALFUNC blnr LoadMacRom(void)
321{
322 tMacErr err;
323
324 if ((NULL == rom_path)
325 || (mnvm_fnfErr == (err = LoadMacRomFrom(rom_path))))
326 if (mnvm_fnfErr == (err = LoadMacRomFrom(RomFileName)))
327 {
328 }
329
330 return trueblnr;
331}
332
333/* --- video out --- */
334
335static GtkWidget *drawing_area;
336
337LOCALVAR blnr gBackgroundFlag = falseblnr;
338LOCALVAR blnr gTrueBackgroundFlag = falseblnr;
339LOCALVAR blnr CurSpeedStopped = trueblnr;
340
341LOCALPROC HaveChangedScreenBuff(si4b top, si4b left,
342 si4b bottom, si4b right)
343{
344 guchar graybuf[vMacScreenWidth * vMacScreenHeight];
345
346 {
347 int i;
348 int j;
349 int k;
350 ui3b *p1 = GetCurDrawBuff()
351 + (ui5r)vMacScreenWidth / 8 * top;
352 ui3b *p2 = (ui3b *)graybuf + (ui5r)vMacScreenWidth * top;
353 ui5b t0;
354
355 UnusedParam(left);
356 UnusedParam(right);
357 for (i = bottom - top; --i >= 0; ) {
358 for (j = vMacScreenWidth / 8; --j >= 0; ) {
359 t0 = *p1++;
360 for (k = 8; --k >= 0; ) {
361 *p2++ = ((t0 >> k) & 0x01) - 1;
362 }
363 }
364 }
365 }
366
367 gdk_draw_gray_image(drawing_area->window,
368 drawing_area->style->fg_gc[GTK_WIDGET_STATE(drawing_area)],
369 left /* x */,
370 top /* y */,
371 right - left /* width */,
372 bottom - top /* height */,
373 GDK_RGB_DITHER_NONE,
374 graybuf + left + (ui5r)vMacScreenWidth * top,
375 vMacScreenWidth);
376}
377
378LOCALPROC MyDrawChangesAndClear(void)
379{
380 if (ScreenChangedBottom > ScreenChangedTop) {
381 HaveChangedScreenBuff(ScreenChangedTop, ScreenChangedLeft,
382 ScreenChangedBottom, ScreenChangedRight);
383 ScreenClearChanges();
384 }
385}
386
387GLOBALOSGLUPROC DoneWithDrawingForTick(void)
388{
389 MyDrawChangesAndClear();
390}
391
392/* --- mouse --- */
393
394LOCALVAR blnr HaveCursorHidden = falseblnr;
395LOCALVAR blnr WantCursorHidden = falseblnr;
396
397static GdkCursor *blank_cursor;
398static GtkWidget *window = NULL;
399
400LOCALPROC ForceShowCursor(void)
401{
402 if (HaveCursorHidden) {
403 HaveCursorHidden = falseblnr;
404
405 if (window) {
406 gdk_window_set_cursor(window->window, NULL);
407 }
408 }
409}
410
411/* cursor state */
412
413LOCALPROC MousePositionNotify(int NewMousePosh, int NewMousePosv)
414{
415 blnr ShouldHaveCursorHidden = trueblnr;
416
417 {
418 if (NewMousePosh < 0) {
419 NewMousePosh = 0;
420 ShouldHaveCursorHidden = falseblnr;
421 } else if (NewMousePosh >= vMacScreenWidth) {
422 NewMousePosh = vMacScreenWidth - 1;
423 ShouldHaveCursorHidden = falseblnr;
424 }
425 if (NewMousePosv < 0) {
426 NewMousePosv = 0;
427 ShouldHaveCursorHidden = falseblnr;
428 } else if (NewMousePosv >= vMacScreenHeight) {
429 NewMousePosv = vMacScreenHeight - 1;
430 ShouldHaveCursorHidden = falseblnr;
431 }
432
433
434 /* if (ShouldHaveCursorHidden || CurMouseButton) */
435 /*
436 for a game like arkanoid, would like mouse to still
437 move even when outside window in one direction
438 */
439 MyMousePositionSet(NewMousePosh, NewMousePosv);
440 }
441
442 WantCursorHidden = ShouldHaveCursorHidden;
443}
444
445LOCALPROC CheckMouseState(void)
446{
447#if 0
448 gint x;
449 gint y;
450 gint x0;
451 gint y0;
452
453 gdk_display_get_pointer(gdk_drawable_get_display(window),
454 NULL, &x, &y, NULL);
455 (void) gdk_window_get_origin(window, &x0, &y0);
456 MousePositionNotify(x - x0, y - y0);
457#endif
458 gint x;
459 gint y;
460
461 gtk_widget_get_pointer(drawing_area, &x, &y);
462 /* (void) gdk_window_get_pointer(window, &x, &y, NULL); */
463 MousePositionNotify(x, y);
464}
465
466/* --- keyboard input --- */
467
468#define MaxNumKeycode 256
469#define KeyCodeMask (MaxNumKeycode - 1)
470 /*
471 assume keycodes >= 0 and < MaxNumKeycode, which
472 isn't promised by gtk documentation.
473 */
474
475
476LOCALVAR ui3b KC2MKC[MaxNumKeycode];
477
478LOCALPROC KC2MKCAssignOne(guint keyval, ui3r key)
479{
480 GdkKeymapKey *keys;
481 gint n_keys;
482 int i;
483
484 if (gdk_keymap_get_entries_for_keyval(NULL,
485 keyval, &keys, &n_keys))
486 {
487 for (i = 0; i < n_keys; i++) {
488 KC2MKC[keys[i].keycode & KeyCodeMask] = key;
489 }
490 g_free(keys);
491 }
492#if 0
493 fprintf(stderr, "%d %d %d\n", (int)ks, key, (int)code);
494#endif
495}
496
497LOCALFUNC blnr KC2MKCInit(void)
498{
499 int i;
500
501 for (i = 0; i < 256; ++i) {
502 KC2MKC[i] = MKC_None;
503 }
504
505#ifdef GDK_KP_Insert
506 KC2MKCAssignOne(GDK_KP_Insert, MKC_KP0);
507#endif
508#ifdef GDK_KP_End
509 KC2MKCAssignOne(GDK_KP_End, MKC_KP1);
510#endif
511#ifdef GDK_KP_Down
512 KC2MKCAssignOne(GDK_KP_Down, MKC_KP2);
513#endif
514#ifdef GDK_KP_Next
515 KC2MKCAssignOne(GDK_KP_Next, MKC_KP3);
516#endif
517#ifdef GDK_KP_Left
518 KC2MKCAssignOne(GDK_KP_Left, MKC_KP4);
519#endif
520#ifdef GDK_KP_Begin
521 KC2MKCAssignOne(GDK_KP_Begin, MKC_KP5);
522#endif
523#ifdef GDK_KP_Right
524 KC2MKCAssignOne(GDK_KP_Right, MKC_KP6);
525#endif
526#ifdef GDK_KP_Home
527 KC2MKCAssignOne(GDK_KP_Home, MKC_KP7);
528#endif
529#ifdef GDK_KP_Up
530 KC2MKCAssignOne(GDK_KP_Up, MKC_KP8);
531#endif
532#ifdef GDK_KP_Prior
533 KC2MKCAssignOne(GDK_KP_Prior, MKC_KP9);
534#endif
535#ifdef GDK_KP_Delete
536 KC2MKCAssignOne(GDK_KP_Delete, MKC_Decimal);
537#endif
538
539 KC2MKCAssignOne(GDK_asciitilde, MKC_formac_Grave);
540 KC2MKCAssignOne(GDK_underscore, MKC_Minus);
541 KC2MKCAssignOne(GDK_plus, MKC_Equal);
542 KC2MKCAssignOne(GDK_braceleft, MKC_LeftBracket);
543 KC2MKCAssignOne(GDK_braceright, MKC_RightBracket);
544 KC2MKCAssignOne(GDK_bar, MKC_formac_BackSlash);
545 KC2MKCAssignOne(GDK_colon, MKC_SemiColon);
546 KC2MKCAssignOne(GDK_quotedbl, MKC_SingleQuote);
547 KC2MKCAssignOne(GDK_less, MKC_Comma);
548 KC2MKCAssignOne(GDK_greater, MKC_Period);
549 KC2MKCAssignOne(GDK_question, MKC_formac_Slash);
550
551 KC2MKCAssignOne(GDK_a, MKC_A);
552 KC2MKCAssignOne(GDK_b, MKC_B);
553 KC2MKCAssignOne(GDK_c, MKC_C);
554 KC2MKCAssignOne(GDK_d, MKC_D);
555 KC2MKCAssignOne(GDK_e, MKC_E);
556 KC2MKCAssignOne(GDK_f, MKC_F);
557 KC2MKCAssignOne(GDK_g, MKC_G);
558 KC2MKCAssignOne(GDK_h, MKC_H);
559 KC2MKCAssignOne(GDK_i, MKC_I);
560 KC2MKCAssignOne(GDK_j, MKC_J);
561 KC2MKCAssignOne(GDK_k, MKC_K);
562 KC2MKCAssignOne(GDK_l, MKC_L);
563 KC2MKCAssignOne(GDK_m, MKC_M);
564 KC2MKCAssignOne(GDK_n, MKC_N);
565 KC2MKCAssignOne(GDK_o, MKC_O);
566 KC2MKCAssignOne(GDK_p, MKC_P);
567 KC2MKCAssignOne(GDK_q, MKC_Q);
568 KC2MKCAssignOne(GDK_r, MKC_R);
569 KC2MKCAssignOne(GDK_s, MKC_S);
570 KC2MKCAssignOne(GDK_t, MKC_T);
571 KC2MKCAssignOne(GDK_u, MKC_U);
572 KC2MKCAssignOne(GDK_v, MKC_V);
573 KC2MKCAssignOne(GDK_w, MKC_W);
574 KC2MKCAssignOne(GDK_x, MKC_X);
575 KC2MKCAssignOne(GDK_y, MKC_Y);
576 KC2MKCAssignOne(GDK_z, MKC_Z);
577
578 /*
579 main mappings
580 */
581
582 KC2MKCAssignOne(GDK_F1, MKC_formac_F1);
583 KC2MKCAssignOne(GDK_F2, MKC_formac_F2);
584 KC2MKCAssignOne(GDK_F3, MKC_formac_F3);
585 KC2MKCAssignOne(GDK_F4, MKC_formac_F4);
586 KC2MKCAssignOne(GDK_F5, MKC_formac_F5);
587 KC2MKCAssignOne(GDK_F6, MKC_F6);
588 KC2MKCAssignOne(GDK_F7, MKC_F7);
589 KC2MKCAssignOne(GDK_F8, MKC_F8);
590 KC2MKCAssignOne(GDK_F9, MKC_F9);
591 KC2MKCAssignOne(GDK_F10, MKC_F10);
592 KC2MKCAssignOne(GDK_F11, MKC_F11);
593 KC2MKCAssignOne(GDK_F12, MKC_F12);
594
595#ifdef GDK_Delete
596 KC2MKCAssignOne(GDK_Delete, MKC_formac_ForwardDel);
597#endif
598#ifdef GDK_Insert
599 KC2MKCAssignOne(GDK_Insert, MKC_formac_Help);
600#endif
601#ifdef GDK_Help
602 KC2MKCAssignOne(GDK_Help, MKC_formac_Help);
603#endif
604#ifdef GDK_Home
605 KC2MKCAssignOne(GDK_Home, MKC_formac_Home);
606#endif
607#ifdef GDK_End
608 KC2MKCAssignOne(GDK_End, MKC_formac_End);
609#endif
610
611#ifdef GDK_Page_Up
612 KC2MKCAssignOne(GDK_Page_Up, MKC_formac_PageUp);
613#else
614#ifdef GDK_Prior
615 KC2MKCAssignOne(GDK_Prior, MKC_formac_PageUp);
616#endif
617#endif
618
619#ifdef GDK_Page_Down
620 KC2MKCAssignOne(GDK_Page_Down, MKC_formac_PageDown);
621#else
622#ifdef GDK_Next
623 KC2MKCAssignOne(GDK_Next, MKC_formac_PageDown);
624#endif
625#endif
626
627#ifdef GDK_Print
628 KC2MKCAssignOne(GDK_Print, MKC_Print);
629#endif
630#ifdef GDK_Scroll_Lock
631 KC2MKCAssignOne(GDK_Scroll_Lock, MKC_ScrollLock);
632#endif
633#ifdef GDK_Pause
634 KC2MKCAssignOne(GDK_Pause, MKC_Pause);
635#endif
636
637 KC2MKCAssignOne(GDK_KP_Add, MKC_KPAdd);
638 KC2MKCAssignOne(GDK_KP_Subtract, MKC_KPSubtract);
639 KC2MKCAssignOne(GDK_KP_Multiply, MKC_KPMultiply);
640 KC2MKCAssignOne(GDK_KP_Divide, MKC_KPDevide);
641 KC2MKCAssignOne(GDK_KP_Enter, MKC_formac_Enter);
642 KC2MKCAssignOne(GDK_KP_Equal, MKC_KPEqual);
643
644 KC2MKCAssignOne(GDK_KP_0, MKC_KP0);
645 KC2MKCAssignOne(GDK_KP_1, MKC_KP1);
646 KC2MKCAssignOne(GDK_KP_2, MKC_KP2);
647 KC2MKCAssignOne(GDK_KP_3, MKC_KP3);
648 KC2MKCAssignOne(GDK_KP_4, MKC_KP4);
649 KC2MKCAssignOne(GDK_KP_5, MKC_KP5);
650 KC2MKCAssignOne(GDK_KP_6, MKC_KP6);
651 KC2MKCAssignOne(GDK_KP_7, MKC_KP7);
652 KC2MKCAssignOne(GDK_KP_8, MKC_KP8);
653 KC2MKCAssignOne(GDK_KP_9, MKC_KP9);
654 KC2MKCAssignOne(GDK_KP_Decimal, MKC_Decimal);
655
656 KC2MKCAssignOne(GDK_Left, MKC_Left);
657 KC2MKCAssignOne(GDK_Right, MKC_Right);
658 KC2MKCAssignOne(GDK_Up, MKC_Up);
659 KC2MKCAssignOne(GDK_Down, MKC_Down);
660
661 KC2MKCAssignOne(GDK_grave, MKC_formac_Grave);
662 KC2MKCAssignOne(GDK_minus, MKC_Minus);
663 KC2MKCAssignOne(GDK_equal, MKC_Equal);
664 KC2MKCAssignOne(GDK_bracketleft, MKC_LeftBracket);
665 KC2MKCAssignOne(GDK_bracketright, MKC_RightBracket);
666 KC2MKCAssignOne(GDK_backslash, MKC_formac_BackSlash);
667 KC2MKCAssignOne(GDK_semicolon, MKC_SemiColon);
668 KC2MKCAssignOne(GDK_apostrophe, MKC_SingleQuote);
669 KC2MKCAssignOne(GDK_comma, MKC_Comma);
670 KC2MKCAssignOne(GDK_period, MKC_Period);
671 KC2MKCAssignOne(GDK_slash, MKC_formac_Slash);
672
673 KC2MKCAssignOne(GDK_Escape, MKC_formac_Escape);
674
675 KC2MKCAssignOne(GDK_Tab, MKC_Tab);
676 KC2MKCAssignOne(GDK_Return, MKC_Return);
677 KC2MKCAssignOne(GDK_space, MKC_Space);
678 KC2MKCAssignOne(GDK_BackSpace, MKC_BackSpace);
679
680 KC2MKCAssignOne(GDK_Caps_Lock, MKC_formac_CapsLock);
681 KC2MKCAssignOne(GDK_Num_Lock, MKC_Clear);
682
683 KC2MKCAssignOne(GDK_Meta_L, MKC_formac_Command);
684
685 KC2MKCAssignOne(GDK_Meta_R, MKC_formac_RCommand);
686
687 KC2MKCAssignOne(GDK_Mode_switch, MKC_formac_Option);
688 KC2MKCAssignOne(GDK_Menu, MKC_formac_Option);
689 KC2MKCAssignOne(GDK_Super_L, MKC_formac_Option);
690 KC2MKCAssignOne(GDK_Super_R, MKC_formac_ROption);
691 KC2MKCAssignOne(GDK_Hyper_L, MKC_formac_Option);
692 KC2MKCAssignOne(GDK_Hyper_R, MKC_formac_ROption);
693
694 KC2MKCAssignOne(GDK_F13, MKC_formac_Option);
695 /*
696 seen being used in Mandrake Linux 9.2
697 for windows key
698 */
699
700 KC2MKCAssignOne(GDK_Shift_L, MKC_formac_Shift);
701 KC2MKCAssignOne(GDK_Shift_R, MKC_formac_RShift);
702
703 KC2MKCAssignOne(GDK_Alt_L, MKC_formac_Command);
704
705 KC2MKCAssignOne(GDK_Alt_R, MKC_formac_RCommand);
706
707 KC2MKCAssignOne(GDK_Control_L, MKC_formac_Control);
708
709 KC2MKCAssignOne(GDK_Control_R, MKC_formac_RControl);
710
711 KC2MKCAssignOne(GDK_1, MKC_1);
712 KC2MKCAssignOne(GDK_2, MKC_2);
713 KC2MKCAssignOne(GDK_3, MKC_3);
714 KC2MKCAssignOne(GDK_4, MKC_4);
715 KC2MKCAssignOne(GDK_5, MKC_5);
716 KC2MKCAssignOne(GDK_6, MKC_6);
717 KC2MKCAssignOne(GDK_7, MKC_7);
718 KC2MKCAssignOne(GDK_8, MKC_8);
719 KC2MKCAssignOne(GDK_9, MKC_9);
720 KC2MKCAssignOne(GDK_0, MKC_0);
721
722 KC2MKCAssignOne(GDK_A, MKC_A);
723 KC2MKCAssignOne(GDK_B, MKC_B);
724 KC2MKCAssignOne(GDK_C, MKC_C);
725 KC2MKCAssignOne(GDK_D, MKC_D);
726 KC2MKCAssignOne(GDK_E, MKC_E);
727 KC2MKCAssignOne(GDK_F, MKC_F);
728 KC2MKCAssignOne(GDK_G, MKC_G);
729 KC2MKCAssignOne(GDK_H, MKC_H);
730 KC2MKCAssignOne(GDK_I, MKC_I);
731 KC2MKCAssignOne(GDK_J, MKC_J);
732 KC2MKCAssignOne(GDK_K, MKC_K);
733 KC2MKCAssignOne(GDK_L, MKC_L);
734 KC2MKCAssignOne(GDK_M, MKC_M);
735 KC2MKCAssignOne(GDK_N, MKC_N);
736 KC2MKCAssignOne(GDK_O, MKC_O);
737 KC2MKCAssignOne(GDK_P, MKC_P);
738 KC2MKCAssignOne(GDK_Q, MKC_Q);
739 KC2MKCAssignOne(GDK_R, MKC_R);
740 KC2MKCAssignOne(GDK_S, MKC_S);
741 KC2MKCAssignOne(GDK_T, MKC_T);
742 KC2MKCAssignOne(GDK_U, MKC_U);
743 KC2MKCAssignOne(GDK_V, MKC_V);
744 KC2MKCAssignOne(GDK_W, MKC_W);
745 KC2MKCAssignOne(GDK_X, MKC_X);
746 KC2MKCAssignOne(GDK_Y, MKC_Y);
747 KC2MKCAssignOne(GDK_Z, MKC_Z);
748
749 InitKeyCodes();
750
751 return trueblnr;
752}
753
754LOCALPROC CheckTheCapsLock(void)
755{
756 GdkModifierType mask;
757
758 (void) gdk_window_get_pointer(window->window, NULL, NULL, &mask);
759
760 Keyboard_UpdateKeyMap2(MKC_formac_CapsLock,
761 (mask & GDK_LOCK_MASK) != 0);
762}
763
764LOCALPROC DoKeyCode(guint keycode, blnr down)
765{
766 if (GDK_Caps_Lock == keycode) {
767 CheckTheCapsLock();
768 } else {
769 ui3r key = KC2MKC[keycode & KeyCodeMask];
770
771 if (MKC_None != key) {
772 Keyboard_UpdateKeyMap2(key, down);
773 }
774 }
775}
776
777/* --- time, date, location --- */
778
779LOCALVAR ui5b TrueEmulatedTime = 0;
780
781#include "DATE2SEC.h"
782
783#define TicksPerSecond 1000000
784
785LOCALVAR blnr HaveTimeDelta = falseblnr;
786LOCALVAR ui5b TimeDelta;
787
788LOCALVAR ui5b NewMacDateInSeconds;
789
790LOCALVAR ui5b LastTimeSec;
791LOCALVAR ui5b LastTimeUsec;
792
793LOCALPROC GetCurrentTicks(void)
794{
795 GTimeVal t;
796
797 g_get_current_time(&t);
798 if (! HaveTimeDelta) {
799 time_t Current_Time;
800 struct tm *s;
801
802#if 0
803 GDate *date;
804 date = g_date_new();
805 g_date_set_time_val(date, &t);
806 g_date_free(date);
807#endif
808 (void) time(&Current_Time);
809 s = localtime(&Current_Time);
810 TimeDelta = Date2MacSeconds(s->tm_sec, s->tm_min, s->tm_hour,
811 s->tm_mday, 1 + s->tm_mon, 1900 + s->tm_year) - t.tv_sec;
812#if 0 && AutoTimeZone /* how portable is this ? */
813 CurMacDelta = ((ui5b)(s->tm_gmtoff) & 0x00FFFFFF)
814 | ((s->tm_isdst ? 0x80 : 0) << 24);
815#endif
816 HaveTimeDelta = trueblnr;
817 }
818
819 NewMacDateInSeconds = t.tv_sec + TimeDelta;
820 LastTimeSec = (ui5b)t.tv_sec;
821 LastTimeUsec = (ui5b)t.tv_usec;
822}
823
824#define MyInvTimeStep 16626 /* TicksPerSecond / 60.14742 */
825
826LOCALVAR ui5b NextTimeSec;
827LOCALVAR ui5b NextTimeUsec;
828
829LOCALPROC IncrNextTime(void)
830{
831 NextTimeUsec += MyInvTimeStep;
832 if (NextTimeUsec >= TicksPerSecond) {
833 NextTimeUsec -= TicksPerSecond;
834 NextTimeSec += 1;
835 }
836}
837
838LOCALPROC InitNextTime(void)
839{
840 NextTimeSec = LastTimeSec;
841 NextTimeUsec = LastTimeUsec;
842 IncrNextTime();
843}
844
845LOCALPROC StartUpTimeAdjust(void)
846{
847 GetCurrentTicks();
848 InitNextTime();
849}
850
851LOCALFUNC si5b GetTimeDiff(void)
852{
853 return ((si5b)(LastTimeSec - NextTimeSec)) * TicksPerSecond
854 + ((si5b)(LastTimeUsec - NextTimeUsec));
855}
856
857LOCALPROC UpdateTrueEmulatedTime(void)
858{
859 si5b TimeDiff;
860
861 GetCurrentTicks();
862
863 TimeDiff = GetTimeDiff();
864 if (TimeDiff >= 0) {
865 if (TimeDiff > 4 * MyInvTimeStep) {
866 /* emulation interrupted, forget it */
867 ++TrueEmulatedTime;
868 InitNextTime();
869 } else {
870 do {
871 ++TrueEmulatedTime;
872 IncrNextTime();
873 TimeDiff -= TicksPerSecond;
874 } while (TimeDiff >= 0);
875 }
876 } else if (TimeDiff < - 2 * MyInvTimeStep) {
877 /* clock goofed if ever get here, reset */
878 InitNextTime();
879 }
880}
881
882LOCALFUNC blnr CheckDateTime(void)
883{
884 if (CurMacDateInSeconds != NewMacDateInSeconds) {
885 CurMacDateInSeconds = NewMacDateInSeconds;
886 return trueblnr;
887 } else {
888 return falseblnr;
889 }
890}
891
892LOCALFUNC blnr InitLocationDat(void)
893{
894 GetCurrentTicks();
895 CurMacDateInSeconds = NewMacDateInSeconds;
896
897 return trueblnr;
898}
899
900/* --- basic dialogs --- */
901
902LOCALPROC CheckSavedMacMsg(void)
903{
904 if (nullpr != SavedBriefMsg) {
905 char briefMsg0[ClStrMaxLength + 1];
906 char longMsg0[ClStrMaxLength + 1];
907
908 NativeStrFromCStr(briefMsg0, SavedBriefMsg, falseblnr);
909 NativeStrFromCStr(longMsg0, SavedLongMsg, falseblnr);
910
911 fprintf(stderr, "%s\n", briefMsg0);
912 fprintf(stderr, "%s\n", longMsg0);
913
914 SavedBriefMsg = nullpr;
915 }
916}
917
918LOCALVAR blnr CaughtMouse = falseblnr;
919
920/* --- main window creation and disposal --- */
921
922LOCALVAR int my_argc;
923LOCALVAR char **my_argv;
924
925/* Create a new backing pixmap of the appropriate size */
926static gboolean configure_event(GtkWidget *widget,
927 GdkEventConfigure *event)
928{
929 return TRUE;
930}
931
932/* Redraw the screen from the backing pixmap */
933static gboolean expose_event(GtkWidget *widget,
934 GdkEventExpose *event,
935 gpointer user_data)
936{
937 int x0 = event->area.x;
938 int y0 = event->area.y;
939 int x1 = x0 + event->area.width;
940 int y1 = y0 + event->area.height;
941
942#if 0 && MyDbgEvents
943 fprintf(stderr, "- event - Expose\n");
944#endif
945
946 if (x0 < 0) {
947 x0 = 0;
948 }
949 if (x1 > vMacScreenWidth) {
950 x1 = vMacScreenWidth;
951 }
952 if (y0 < 0) {
953 y0 = 0;
954 }
955 if (y1 > vMacScreenHeight) {
956 y1 = vMacScreenHeight;
957 }
958 if ((x0 < x1) && (y0 < y1)) {
959 HaveChangedScreenBuff(y0, x0, y1, x1);
960 }
961
962 return FALSE;
963}
964
965static gboolean button_press_event(GtkWidget *widget,
966 GdkEventButton *event,
967 gpointer user_data)
968{
969 MousePositionNotify(event->x, event->y);
970 MyMouseButtonSet(trueblnr);
971
972 return TRUE;
973}
974
975static gboolean button_release_event(GtkWidget *widget,
976 GdkEventButton *event,
977 gpointer user_data)
978{
979 MousePositionNotify(event->x, event->y);
980 MyMouseButtonSet(falseblnr);
981
982 return TRUE;
983}
984
985static gboolean motion_notify_event(GtkWidget *widget,
986 GdkEventMotion *event,
987 gpointer user_data)
988{
989 int x;
990 int y;
991 GdkModifierType state;
992
993 if (event->is_hint) {
994 gdk_window_get_pointer(event->window, &x, &y, &state);
995 } else {
996 x = event->x;
997 y = event->y;
998 state = event->state;
999 }
1000
1001 MousePositionNotify(x, y);
1002 MyMouseButtonSet((state & GDK_BUTTON1_MASK) != 0);
1003
1004 return TRUE;
1005}
1006
1007static gboolean enter_notify_event(GtkWidget *widget,
1008 GdkEventCrossing *event,
1009 gpointer user_data)
1010{
1011 CaughtMouse = trueblnr;
1012
1013 MousePositionNotify(event->x, event->y);
1014 MyMouseButtonSet((event->state & GDK_BUTTON1_MASK) != 0);
1015
1016 return TRUE;
1017}
1018
1019static gboolean leave_notify_event(GtkWidget *widget,
1020 GdkEventCrossing *event,
1021 gpointer user_data)
1022{
1023 MousePositionNotify(event->x, event->y);
1024 MyMouseButtonSet((event->state & GDK_BUTTON1_MASK) != 0);
1025
1026 CaughtMouse = falseblnr;
1027
1028 return TRUE;
1029}
1030
1031static gboolean delete_event(GtkWidget *widget,
1032 GdkEventMotion *event)
1033{
1034 RequestMacOff = trueblnr;
1035
1036 return TRUE;
1037}
1038
1039LOCALPROC ReconnectKeyCodes3(void)
1040{
1041 CheckTheCapsLock();
1042
1043#if 0
1044 if (WantCmdOptOnReconnect) {
1045 WantCmdOptOnReconnect = falseblnr;
1046
1047 GetTheDownKeys();
1048 }
1049#endif
1050}
1051
1052LOCALPROC DisconnectKeyCodes3(void)
1053{
1054 DisconnectKeyCodes2();
1055 MyMouseButtonSet(falseblnr);
1056}
1057
1058LOCALVAR blnr ADialogIsUp = falseblnr;
1059
1060LOCALPROC MyBeginDialog(void)
1061{
1062 DisconnectKeyCodes3();
1063 ADialogIsUp = trueblnr;
1064 ForceShowCursor();
1065}
1066
1067LOCALPROC MyEndDialog(void)
1068{
1069 ADialogIsUp = falseblnr;
1070 ReconnectKeyCodes3();
1071}
1072
1073/* --- SavedTasks --- */
1074
1075LOCALPROC LeaveBackground(void)
1076{
1077 ReconnectKeyCodes3();
1078#if 0
1079 DisableKeyRepeat();
1080#endif
1081}
1082
1083LOCALPROC EnterBackground(void)
1084{
1085#if 0
1086 RestoreKeyRepeat();
1087#endif
1088 DisconnectKeyCodes3();
1089
1090 ForceShowCursor();
1091}
1092
1093LOCALPROC LeaveSpeedStopped(void)
1094{
1095 StartUpTimeAdjust();
1096}
1097
1098LOCALPROC EnterSpeedStopped(void)
1099{
1100}
1101
1102static void InsertADisk0(void)
1103{
1104 char ts[ClStrMaxLength + 1];
1105 GtkWidget *dialog;
1106
1107 NativeStrFromCStr(ts, kStrMenuItemOpen, falseblnr);
1108
1109 MyBeginDialog();
1110 dialog = gtk_file_chooser_dialog_new(ts,
1111 GTK_WINDOW(window),
1112 GTK_FILE_CHOOSER_ACTION_OPEN,
1113 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1114 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
1115 NULL);
1116 MyEndDialog();
1117
1118 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1119 char *filename;
1120
1121 filename =
1122 gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
1123 (void) Sony_Insert1a(filename, falseblnr);
1124 g_free(filename);
1125 }
1126
1127 gtk_widget_destroy(dialog);
1128}
1129
1130LOCALPROC CheckForSavedTasks(void)
1131{
1132 if (MyEvtQNeedRecover) {
1133 MyEvtQNeedRecover = falseblnr;
1134
1135 /* attempt cleanup, MyEvtQNeedRecover may get set again */
1136 MyEvtQTryRecoverFromFull();
1137 }
1138
1139 if (RequestMacOff) {
1140 RequestMacOff = falseblnr;
1141 if (AnyDiskInserted()) {
1142 MacMsgOverride(kStrQuitWarningTitle,
1143 kStrQuitWarningMessage);
1144 } else {
1145 ForceMacOff = trueblnr;
1146 }
1147 }
1148
1149 if (ForceMacOff) {
1150 return;
1151 }
1152
1153 if (gTrueBackgroundFlag != gBackgroundFlag) {
1154 gBackgroundFlag = gTrueBackgroundFlag;
1155 if (gTrueBackgroundFlag) {
1156 EnterBackground();
1157 } else {
1158 LeaveBackground();
1159 }
1160 }
1161
1162 if (CurSpeedStopped != (SpeedStopped ||
1163 (gBackgroundFlag && ! RunInBackground
1164#if EnableAutoSlow && 0
1165 && (QuietSubTicks >= 4092)
1166#endif
1167 )))
1168 {
1169 CurSpeedStopped = ! CurSpeedStopped;
1170 if (CurSpeedStopped) {
1171 EnterSpeedStopped();
1172 } else {
1173 LeaveSpeedStopped();
1174 }
1175 }
1176
1177
1178 if ((nullpr != SavedBriefMsg) & ! MacMsgDisplayed) {
1179 MacMsgDisplayOn();
1180 }
1181
1182 if (NeedWholeScreenDraw) {
1183 NeedWholeScreenDraw = falseblnr;
1184 ScreenChangedAll();
1185 }
1186
1187 if (HaveCursorHidden != (WantCursorHidden && CaughtMouse
1188 && ! (gTrueBackgroundFlag || ADialogIsUp || CurSpeedStopped)))
1189 {
1190 HaveCursorHidden = ! HaveCursorHidden;
1191 if (HaveCursorHidden) {
1192 gdk_window_set_cursor(window->window, blank_cursor);
1193 } else {
1194 gdk_window_set_cursor(window->window, NULL);
1195 }
1196 }
1197
1198 if (gTrueBackgroundFlag || ADialogIsUp) {
1199 } else {
1200 if (RequestInsertDisk) {
1201 RequestInsertDisk = falseblnr;
1202 InsertADisk0();
1203 }
1204 }
1205
1206#if NeedRequestIthDisk
1207 if (0 != RequestIthDisk) {
1208 Sony_InsertIth(RequestIthDisk);
1209 RequestIthDisk = 0;
1210 }
1211#endif
1212}
1213
1214/* --- command line parsing --- */
1215
1216LOCALFUNC blnr ScanCommandLine(void)
1217{
1218 int i;
1219
1220 for (i = 1; i < my_argc; ++i) {
1221 if ('-' == my_argv[i][0]) {
1222#if 0
1223 if ((0 == strcmp(my_argv[i], "--display")) ||
1224 (0 == strcmp(my_argv[i], "-display")))
1225 {
1226 ++i;
1227 if (i < my_argc) {
1228 display_name = my_argv[i];
1229 }
1230 } else
1231#endif
1232 if ((0 == strcmp(my_argv[i], "--rom")) ||
1233 (0 == strcmp(my_argv[i], "-r")))
1234 {
1235 ++i;
1236 if (i < my_argc) {
1237 rom_path = my_argv[i];
1238 }
1239 } else
1240#if 0
1241 if (0 == strcmp(my_argv[i], "-l")) {
1242 SpeedValue = 0;
1243 } else
1244#endif
1245 {
1246 MacMsg(kStrBadArgTitle, kStrBadArgMessage, falseblnr);
1247 }
1248 } else {
1249 (void) Sony_Insert1(my_argv[i], falseblnr);
1250 }
1251 }
1252 return trueblnr;
1253}
1254
1255/* --- main program flow --- */
1256
1257GLOBALOSGLUFUNC blnr ExtraTimeNotOver(void)
1258{
1259 UpdateTrueEmulatedTime();
1260 return TrueEmulatedTime == OnTrueTime;
1261}
1262
1263LOCALPROC WaitForTheNextEvent(void)
1264{
1265 (void) gtk_main_iteration_do(TRUE);
1266}
1267
1268LOCALPROC CheckForSystemEvents(void)
1269{
1270 int i = 10;
1271
1272 while (gtk_events_pending() && (--i >= 0)) {
1273 (void) gtk_main_iteration_do(FALSE);
1274 }
1275#if 0
1276 XFlush(x_display);
1277#endif
1278}
1279
1280GLOBALOSGLUPROC WaitForNextTick(void)
1281{
1282label_retry:
1283 CheckForSystemEvents();
1284 CheckForSavedTasks();
1285 if (ForceMacOff) {
1286 return;
1287 }
1288
1289 if (CurSpeedStopped) {
1290 DoneWithDrawingForTick();
1291 WaitForTheNextEvent();
1292 goto label_retry;
1293 }
1294
1295 if (ExtraTimeNotOver()) {
1296 si5b TimeDiff = GetTimeDiff();
1297 if (TimeDiff < 0) {
1298 g_usleep(- TimeDiff);
1299 }
1300 goto label_retry;
1301 }
1302
1303 if (CheckDateTime()) {
1304#if EnableDemoMsg
1305 DemoModeSecondNotify();
1306#endif
1307 }
1308
1309 if ((! gBackgroundFlag || ADialogIsUp)
1310 && (! CaughtMouse)
1311 )
1312 {
1313 CheckMouseState();
1314 }
1315
1316 OnTrueTime = TrueEmulatedTime;
1317}
1318
1319#include "PROGMAIN.h"
1320
1321static gboolean
1322MainEventLoop0(gpointer data)
1323{
1324 (void) data;
1325 fprintf(stderr, "hello from MainEventLoop0\n");
1326 ProgramMain();
1327 if (ForceMacOff) {
1328 goto Label_01;
1329 }
1330#if 0
1331 while (! gtk_main_iteration_do(FALSE)) {
1332 if (! gtk_events_pending()) {
1333 fprintf(stderr, "sleep\n");
1334 g_usleep(1000000);
1335 }
1336 }
1337#endif
1338Label_01:
1339 fprintf(stderr, "leaving MainEventLoop0\n");
1340
1341 gtk_main_quit();
1342
1343 return FALSE;
1344}
1345
1346static gboolean
1347focus_in_event(GtkWidget *widget, GdkEvent *event,
1348 gpointer data)
1349{
1350 gTrueBackgroundFlag = falseblnr;
1351
1352 CheckMouseState();
1353
1354 return FALSE;
1355}
1356
1357static gboolean
1358focus_out_event(GtkWidget *widget, GdkEvent *event,
1359 gpointer data)
1360{
1361 gTrueBackgroundFlag = trueblnr;
1362 return FALSE;
1363}
1364
1365static gboolean key_press_event(GtkWidget *widget,
1366 GdkEventKey *event,
1367 gpointer user_data)
1368{
1369#if 0
1370 fprintf(stderr, "hello from key_press_event\n");
1371 fprintf(stderr, "keyval %d\n", event->keyval);
1372 fprintf(stderr, "hardware_keycode %d\n", event->hardware_keycode);
1373#endif
1374#if 0
1375 {
1376 GdkKeymapKey *keys;
1377 gint n_keys;
1378 int i;
1379
1380 if (gdk_keymap_get_entries_for_keyval(NULL,
1381 event->keyval, &keys, &n_keys))
1382 {
1383 for (i = 0; i < n_keys; i++) {
1384 fprintf(stderr, "keycode %d\n", keys[i].keycode);
1385 }
1386 g_free(keys);
1387 }
1388 }
1389#endif
1390 DoKeyCode(event->hardware_keycode, trueblnr);
1391
1392 return TRUE;
1393}
1394
1395static gboolean key_release_event(GtkWidget *widget,
1396 GdkEventKey *event,
1397 gpointer user_data)
1398{
1399#if 0
1400 fprintf(stderr, "hello from key_release_event\n");
1401 fprintf(stderr, "keyval %d\n", event->keyval);
1402 fprintf(stderr, "hardware_keycode %d\n", event->hardware_keycode);
1403#endif
1404 DoKeyCode(event->hardware_keycode, falseblnr);
1405
1406 return TRUE;
1407}
1408
1409static void drag_data_received(GtkWidget *widget,
1410 GdkDragContext *drag_context,
1411 gint x,
1412 gint y,
1413 GtkSelectionData *data,
1414 guint info,
1415 guint time,
1416 gpointer user_data)
1417{
1418 char **uris;
1419 char *file;
1420 int i;
1421 gboolean handled = FALSE;
1422
1423 uris = g_strsplit((char *)data->data, "\r\n", -1);
1424 if (uris != NULL) {
1425 for (i = 0; uris[i] != NULL; i++) {
1426 file = g_filename_from_uri(uris[i], NULL, NULL);
1427 /* file = gnome_vfs_get_local_path_from_uri(uris[i]); */
1428 if (file != NULL) {
1429 (void) Sony_Insert1a(file, falseblnr);
1430 handled = TRUE;
1431 g_free(file);
1432 }
1433 }
1434 g_strfreev(uris);
1435 }
1436 gtk_drag_finish(drag_context, handled, FALSE, time);
1437 if (handled) {
1438 gtk_window_present_with_time(GTK_WINDOW(window), time);
1439 }
1440}
1441
1442static void do_more_commands_item(GtkAction *action, gpointer user_data)
1443{
1444 DoMoreCommandsMsg();
1445}
1446
1447static void do_about_item(GtkAction *action, gpointer user_data)
1448{
1449 DoAboutMsg();
1450}
1451
1452static void do_quit_item(GtkAction *action, gpointer user_data)
1453{
1454 RequestMacOff = trueblnr;
1455}
1456
1457static void do_open_item(GtkAction *action, gpointer user_data)
1458{
1459 RequestInsertDisk = trueblnr;
1460}
1461
1462LOCALPROC MyAppendConvertMenuItem(GtkWidget *the_menu,
1463 GCallback c_handler, gpointer gobject, char *s, blnr AddEllipsis)
1464{
1465 char ts[ClStrMaxLength + 1];
1466 GtkWidget *the_item;
1467
1468 NativeStrFromCStr(ts, s, AddEllipsis);
1469 the_item = gtk_menu_item_new_with_label(ts);
1470 g_signal_connect(G_OBJECT(the_item), "activate",
1471 c_handler, gobject);
1472 gtk_menu_shell_append(GTK_MENU_SHELL(the_menu), the_item);
1473}
1474
1475LOCALPROC MyAppendSubmenuConvertName(GtkWidget *menubar,
1476 GtkWidget *the_menu, char *s)
1477{
1478 char ts[ClStrMaxLength + 1];
1479 GtkWidget *the_item;
1480
1481 NativeStrFromCStr(ts, s, falseblnr);
1482 the_item = gtk_menu_item_new_with_label(ts);
1483 gtk_menu_item_set_submenu(GTK_MENU_ITEM(the_item), the_menu);
1484 gtk_menu_shell_append(GTK_MENU_SHELL(menubar), the_item);
1485}
1486
1487static GdkPixmap *blank_pixmap;
1488static GdkColor blank_color = {
1489 0, 0, 0, 0
1490};
1491
1492static gchar blank_cursor_bits[] = {
1493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1497};
1498
1499static GtkTargetEntry dnd_target =
1500{
1501 "text/uri-list", 0, 0
1502};
1503
1504LOCALPROC ZapOSGLUVars(void)
1505{
1506 InitDrives();
1507#if 0
1508 {
1509 int i;
1510
1511 for (i = 0; i < kNumMagStates; ++i) {
1512 HavePositionWins[i] = falseblnr;
1513 }
1514 }
1515#endif
1516}
1517
1518LOCALPROC ReserveAllocAll(void)
1519{
1520#if dbglog_HAVE
1521 dbglog_ReserveAlloc();
1522#endif
1523 ReserveAllocOneBlock(&ROM, kROM_Size, 5, falseblnr);
1524 ReserveAllocOneBlock(&screencomparebuff,
1525 vMacScreenNumBytes, 5, trueblnr);
1526#if UseControlKeys
1527 ReserveAllocOneBlock(&CntrlDisplayBuff,
1528 vMacScreenNumBytes, 5, falseblnr);
1529#endif
1530
1531 EmulationReserveAlloc();
1532}
1533
1534LOCALFUNC blnr AllocMyMemory(void)
1535{
1536 uimr n;
1537 blnr IsOk = falseblnr;
1538
1539 ReserveAllocOffset = 0;
1540 ReserveAllocBigBlock = nullpr;
1541 ReserveAllocAll();
1542 n = ReserveAllocOffset;
1543 ReserveAllocBigBlock = (ui3p)calloc(1, n);
1544 if (NULL == ReserveAllocBigBlock) {
1545 MacMsg(kStrOutOfMemTitle, kStrOutOfMemMessage, trueblnr);
1546 } else {
1547 ReserveAllocOffset = 0;
1548 ReserveAllocAll();
1549 if (n != ReserveAllocOffset) {
1550 /* oops, program error */
1551 } else {
1552 IsOk = trueblnr;
1553 }
1554 }
1555
1556 return IsOk;
1557}
1558
1559LOCALPROC UnallocMyMemory(void)
1560{
1561 if (nullpr != ReserveAllocBigBlock) {
1562 free((char *)ReserveAllocBigBlock);
1563 }
1564}
1565
1566LOCALFUNC blnr InitOSGLU(void)
1567{
1568 if (AllocMyMemory())
1569#if dbglog_HAVE
1570 if (dbglog_open())
1571#endif
1572 if (ScanCommandLine())
1573 if (LoadMacRom())
1574 if (LoadInitialImages())
1575 if (InitLocationDat())
1576 /* if (ReCreateMainWindow()) */
1577 if (KC2MKCInit())
1578 if (WaitForRom())
1579 {
1580 return trueblnr;
1581 }
1582 return falseblnr;
1583}
1584
1585LOCALPROC UnInitOSGLU(void)
1586{
1587 if (MacMsgDisplayed) {
1588 MacMsgDisplayOff();
1589 }
1590
1591 UnInitDrives();
1592
1593 ForceShowCursor();
1594
1595#if dbglog_HAVE
1596 dbglog_close();
1597#endif
1598
1599 UnallocMyMemory();
1600
1601 CheckSavedMacMsg();
1602}
1603
1604int main(int argc, char *argv[])
1605{
1606 GtkWidget *vbox;
1607
1608#if 0
1609 GtkWidget *button;
1610#endif
1611
1612 GtkWidget *menubar;
1613 GtkWidget *the_menu;
1614 GtkWidget *the_item;
1615
1616 gtk_init(&argc, &argv);
1617
1618 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1619 gtk_widget_set_name(window, "Test Input");
1620 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
1621
1622 vbox = gtk_vbox_new(FALSE, 0);
1623 gtk_container_add(GTK_CONTAINER(window), vbox);
1624 gtk_widget_show(vbox);
1625
1626 g_signal_connect(G_OBJECT(window), "delete-event",
1627 G_CALLBACK(delete_event), NULL);
1628 g_signal_connect(G_OBJECT(window), "focus-out-event",
1629 (GCallback)focus_out_event,
1630 NULL);
1631 g_signal_connect(G_OBJECT(window), "focus-in-event",
1632 (GCallback)focus_in_event, NULL);
1633
1634 g_signal_connect(G_OBJECT(window), "key-press-event",
1635 G_CALLBACK(key_press_event), NULL);
1636 g_signal_connect(G_OBJECT(window), "key-release-event",
1637 G_CALLBACK(key_release_event), NULL);
1638
1639 menubar = gtk_menu_bar_new();
1640
1641 the_menu = gtk_menu_new();
1642
1643 MyAppendConvertMenuItem(the_menu,
1644 G_CALLBACK(do_open_item), NULL, kStrMenuItemOpen, trueblnr);
1645
1646 the_item = gtk_separator_menu_item_new();
1647 gtk_menu_shell_append(GTK_MENU_SHELL(the_menu), the_item);
1648
1649 MyAppendConvertMenuItem(the_menu,
1650 G_CALLBACK(do_quit_item), NULL, kStrMenuItemQuit, falseblnr);
1651
1652 MyAppendSubmenuConvertName(menubar, the_menu, kStrMenuFile);
1653
1654 the_menu = gtk_menu_new();
1655
1656 MyAppendConvertMenuItem(the_menu, G_CALLBACK(do_more_commands_item),
1657 NULL, kStrMenuItemMore, trueblnr);
1658
1659 MyAppendSubmenuConvertName(menubar, the_menu, kStrMenuSpecial);
1660
1661 the_menu = gtk_menu_new();
1662
1663 MyAppendConvertMenuItem(the_menu,
1664 G_CALLBACK(do_about_item), NULL, kStrMenuItemAbout, trueblnr);
1665
1666 MyAppendSubmenuConvertName(menubar, the_menu, kStrMenuHelp);
1667
1668 gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
1669
1670 gtk_widget_show_all(menubar);
1671
1672
1673 /* Create the drawing area */
1674
1675 drawing_area = gtk_drawing_area_new();
1676 gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
1677 vMacScreenWidth, vMacScreenHeight);
1678 gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
1679
1680 gtk_widget_show(drawing_area);
1681
1682 /* Signals used to handle backing pixmap */
1683
1684 g_signal_connect(G_OBJECT(drawing_area), "expose-event",
1685 G_CALLBACK(expose_event), NULL);
1686 g_signal_connect(G_OBJECT(drawing_area), "configure-event",
1687 G_CALLBACK(configure_event), NULL);
1688
1689 /* Event signals */
1690
1691 g_signal_connect(G_OBJECT(drawing_area), "motion-notify-event",
1692 G_CALLBACK(motion_notify_event), NULL);
1693 g_signal_connect(G_OBJECT(drawing_area), "enter-notify-event",
1694 G_CALLBACK(enter_notify_event), NULL);
1695 g_signal_connect(G_OBJECT(drawing_area), "leave-notify-event",
1696 G_CALLBACK(leave_notify_event), NULL);
1697
1698 g_signal_connect(G_OBJECT(drawing_area), "button-press-event",
1699 G_CALLBACK(button_press_event), NULL);
1700 g_signal_connect(G_OBJECT(drawing_area), "button-release-event",
1701 G_CALLBACK(button_release_event), NULL);
1702
1703 gtk_widget_add_events(window,
1704 GDK_KEY_PRESS_MASK
1705 | GDK_KEY_RELEASE_MASK
1706 );
1707
1708 gtk_widget_set_events(drawing_area, GDK_EXPOSURE_MASK
1709 | GDK_LEAVE_NOTIFY_MASK
1710 | GDK_BUTTON_PRESS_MASK
1711 | GDK_BUTTON_RELEASE_MASK
1712 | GDK_POINTER_MOTION_MASK
1713 | GDK_ENTER_NOTIFY_MASK
1714 | GDK_LEAVE_NOTIFY_MASK
1715 | GDK_FOCUS_CHANGE_MASK
1716 | GDK_KEY_PRESS_MASK
1717 | GDK_KEY_RELEASE_MASK
1718 /* | GDK_POINTER_MOTION_HINT_MASK */
1719 );
1720
1721#if 0
1722 /* .. And a quit button */
1723 button = gtk_button_new_with_label("Quit");
1724 gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
1725
1726 g_signal_connect_swapped(G_OBJECT(button), "clicked",
1727 G_CALLBACK(delete_event), NULL
1728 /*
1729 G_CALLBACK(gtk_widget_destroy),
1730 G_OBJECT(window)
1731 */
1732 );
1733 gtk_widget_show(button);
1734#endif
1735
1736 gtk_drag_dest_set(drawing_area, GTK_DEST_DEFAULT_ALL,
1737 &dnd_target, 1,
1738 GDK_ACTION_COPY);
1739 g_signal_connect(GTK_OBJECT(drawing_area), "drag-data-received",
1740 G_CALLBACK(drag_data_received), NULL);
1741
1742 gtk_widget_show(window);
1743
1744 blank_pixmap = gdk_bitmap_create_from_data(NULL,
1745 blank_cursor_bits, 16, 16);
1746 blank_cursor = gdk_cursor_new_from_pixmap(blank_pixmap,
1747 blank_pixmap, &blank_color, &blank_color, 8, 8);
1748 gdk_pixmap_unref(blank_pixmap);
1749
1750 gdk_window_set_cursor(window->window, blank_cursor);
1751
1752 g_idle_add(MainEventLoop0, NULL);
1753
1754 my_argc = argc;
1755 my_argv = argv;
1756
1757 ZapOSGLUVars();
1758 if (InitOSGLU()) {
1759 gtk_main ();
1760 }
1761 UnInitOSGLU();
1762
1763 return 0;
1764}
1765
1766#endif /* WantOSGLUGTK */