2023-04-28 14:06:51 +02:00
|
|
|
#include "config.h"
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <pwd.h>
|
2015-07-26 11:16:05 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
2022-03-24 13:41:22 +01:00
|
|
|
#include <unistd.h>
|
2015-07-26 11:16:05 +02:00
|
|
|
#include <sys/utsname.h>
|
|
|
|
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_X11 )
|
2015-07-26 11:16:05 +02:00
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xresource.h>
|
2022-03-24 13:41:22 +01:00
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/keysym.h>
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-30 16:34:53 +02:00
|
|
|
#include "icon.h"
|
|
|
|
#endif
|
|
|
|
|
2015-07-26 11:16:05 +02:00
|
|
|
#include "buttons.h"
|
|
|
|
#include "hp.h"
|
2022-03-24 13:41:22 +01:00
|
|
|
#include "small.h"
|
2023-04-27 16:35:56 +02:00
|
|
|
#include "x48_gui.h"
|
2015-07-26 11:16:05 +02:00
|
|
|
#include "constants.h"
|
2022-03-24 13:41:22 +01:00
|
|
|
#include "device.h"
|
|
|
|
#include "errors.h"
|
|
|
|
#include "hp48.h"
|
2015-07-26 11:16:05 +02:00
|
|
|
#include "options.h"
|
|
|
|
#include "resources.h"
|
|
|
|
#include "romio.h"
|
|
|
|
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_X11 )
|
2023-04-27 12:15:59 +02:00
|
|
|
static char* defaults[] = {
|
2023-04-30 18:16:13 +02:00
|
|
|
#include "X48NG.ad.h"
|
2023-04-27 12:15:59 +02:00
|
|
|
0 };
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:30:36 +02:00
|
|
|
extern int XShmQueryExtension( Display* );
|
|
|
|
extern int XShmGetEventBase( Display* );
|
2015-07-26 11:16:05 +02:00
|
|
|
static int CompletionType = -1;
|
|
|
|
#endif
|
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
extern int saved_argc;
|
2023-04-27 12:15:59 +02:00
|
|
|
extern char** saved_argv;
|
2022-03-24 13:41:22 +01:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
Display* dpy;
|
2022-03-24 13:41:22 +01:00
|
|
|
int screen;
|
|
|
|
unsigned int depth;
|
|
|
|
Colormap cmap;
|
|
|
|
GC gc;
|
|
|
|
Window mainW;
|
|
|
|
Window iconW = 0;
|
2023-04-30 16:34:53 +02:00
|
|
|
#endif
|
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
disp_t disp;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_X11 )
|
2022-03-24 13:41:22 +01:00
|
|
|
Atom wm_delete_window, wm_save_yourself, wm_protocols;
|
|
|
|
Atom ol_decor_del, ol_decor_icon_name;
|
|
|
|
Atom atom_type;
|
2023-04-27 12:15:59 +02:00
|
|
|
Visual* visual;
|
2022-03-24 13:41:22 +01:00
|
|
|
Pixmap icon_pix;
|
|
|
|
Pixmap icon_text_pix;
|
|
|
|
Pixmap icon_disp_pix;
|
|
|
|
static int last_icon_state = -1;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_XSHM
|
2022-03-24 13:41:22 +01:00
|
|
|
int shm_flag;
|
|
|
|
int xerror_flag;
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
int dynamic_color;
|
|
|
|
int direct_color;
|
|
|
|
int does_backing_store;
|
|
|
|
int color_mode;
|
|
|
|
int icon_color_mode;
|
2023-04-30 16:34:53 +02:00
|
|
|
#endif
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_SDL1 )
|
2023-04-30 16:34:53 +02:00
|
|
|
keypad_t keypad;
|
|
|
|
color_t* colors;
|
|
|
|
|
|
|
|
// This will take the value of the defines, but can be run-time modified
|
|
|
|
unsigned KEYBOARD_HEIGHT, KEYBOARD_WIDTH, TOP_SKIP, SIDE_SKIP, BOTTOM_SKIP,
|
|
|
|
DISP_KBD_SKIP, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X,
|
|
|
|
DISPLAY_OFFSET_Y, DISP_FRAME, KEYBOARD_OFFSET_X, KEYBOARD_OFFSET_Y,
|
|
|
|
KBD_UPLINE;
|
|
|
|
#endif
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
#if 0
|
2022-03-24 13:41:22 +01:00
|
|
|
#define DEBUG_XEVENT 1
|
|
|
|
#define DEBUG_BUTTONS 1
|
|
|
|
#define DEBUG_FOCUS 1
|
|
|
|
#define DEBUG_BACKING_STORE 1
|
|
|
|
#define DEBUG_SHM 1
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
|
|
|
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_X11 )
|
2015-07-26 11:16:05 +02:00
|
|
|
typedef struct keypad_t {
|
2023-04-27 12:15:59 +02:00
|
|
|
unsigned int width;
|
|
|
|
unsigned int height;
|
|
|
|
Pixmap pixmap;
|
2015-07-26 11:16:05 +02:00
|
|
|
} keypad_t;
|
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
keypad_t keypad;
|
2023-04-27 12:15:59 +02:00
|
|
|
color_t* colors;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-05-02 14:40:02 +02:00
|
|
|
color_t colors_sx[] = {
|
|
|
|
{ "white",
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "left",
|
|
|
|
255,
|
|
|
|
166,
|
|
|
|
0,
|
|
|
|
255,
|
|
|
|
230,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "right",
|
|
|
|
0,
|
|
|
|
210,
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
169,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "but_top",
|
|
|
|
109,
|
|
|
|
93,
|
|
|
|
93,
|
|
|
|
0,
|
|
|
|
91,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "button",
|
|
|
|
90,
|
|
|
|
77,
|
|
|
|
77,
|
|
|
|
0,
|
|
|
|
81,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "but_bot",
|
|
|
|
76,
|
|
|
|
65,
|
|
|
|
65,
|
|
|
|
0,
|
|
|
|
69,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "lcd_col",
|
|
|
|
202,
|
|
|
|
221,
|
|
|
|
92,
|
|
|
|
255,
|
|
|
|
205,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "pix_col",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
128,
|
|
|
|
0,
|
|
|
|
20,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "pad_top",
|
|
|
|
109,
|
|
|
|
78,
|
|
|
|
78,
|
|
|
|
0,
|
|
|
|
88,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "pad", 90, 64, 64, 0, 73, { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "pad_bot",
|
|
|
|
76,
|
|
|
|
54,
|
|
|
|
54,
|
|
|
|
0,
|
|
|
|
60,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "disp_pad_top",
|
|
|
|
155,
|
|
|
|
118,
|
|
|
|
84,
|
|
|
|
0,
|
|
|
|
124,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "disp_pad",
|
|
|
|
124,
|
|
|
|
94,
|
|
|
|
67,
|
|
|
|
0,
|
|
|
|
99,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "disp_pad_bot",
|
|
|
|
100,
|
|
|
|
75,
|
|
|
|
53,
|
|
|
|
0,
|
|
|
|
79,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "logo",
|
|
|
|
204,
|
|
|
|
169,
|
|
|
|
107,
|
|
|
|
255,
|
|
|
|
172,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "logo_back",
|
|
|
|
64,
|
|
|
|
64,
|
|
|
|
64,
|
|
|
|
0,
|
|
|
|
65,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "label",
|
|
|
|
202,
|
|
|
|
184,
|
|
|
|
144,
|
|
|
|
255,
|
|
|
|
185,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "frame", 0, 0, 0, 255, 0, { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "underlay",
|
|
|
|
60,
|
|
|
|
42,
|
|
|
|
42,
|
|
|
|
0,
|
|
|
|
48,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "black", 0, 0, 0, 0, 0, { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ 0 } };
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-02 14:40:02 +02:00
|
|
|
color_t colors_gx[] = {
|
|
|
|
{ "white",
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "left",
|
|
|
|
255,
|
|
|
|
186,
|
|
|
|
255,
|
|
|
|
255,
|
|
|
|
220,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "right",
|
|
|
|
0,
|
|
|
|
255,
|
|
|
|
204,
|
|
|
|
255,
|
|
|
|
169,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "but_top",
|
|
|
|
104,
|
|
|
|
104,
|
|
|
|
104,
|
|
|
|
0,
|
|
|
|
104,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "button",
|
|
|
|
88,
|
|
|
|
88,
|
|
|
|
88,
|
|
|
|
0,
|
|
|
|
88,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "but_bot",
|
|
|
|
74,
|
|
|
|
74,
|
|
|
|
74,
|
|
|
|
0,
|
|
|
|
74,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "lcd_col",
|
|
|
|
202,
|
|
|
|
221,
|
|
|
|
92,
|
|
|
|
255,
|
|
|
|
205,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "pix_col",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
128,
|
|
|
|
0,
|
|
|
|
20,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "pad_top",
|
|
|
|
88,
|
|
|
|
88,
|
|
|
|
88,
|
|
|
|
0,
|
|
|
|
88,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "pad", 74, 74, 74, 0, 74, { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "pad_bot",
|
|
|
|
64,
|
|
|
|
64,
|
|
|
|
64,
|
|
|
|
0,
|
|
|
|
64,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "disp_pad_top",
|
|
|
|
128,
|
|
|
|
128,
|
|
|
|
138,
|
|
|
|
0,
|
|
|
|
128,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "disp_pad",
|
|
|
|
104,
|
|
|
|
104,
|
|
|
|
110,
|
|
|
|
0,
|
|
|
|
104,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "disp_pad_bot",
|
|
|
|
84,
|
|
|
|
84,
|
|
|
|
90,
|
|
|
|
0,
|
|
|
|
84,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "logo",
|
|
|
|
176,
|
|
|
|
176,
|
|
|
|
184,
|
|
|
|
255,
|
|
|
|
176,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "logo_back",
|
|
|
|
104,
|
|
|
|
104,
|
|
|
|
110,
|
|
|
|
0,
|
|
|
|
104,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "label",
|
|
|
|
240,
|
|
|
|
240,
|
|
|
|
240,
|
|
|
|
255,
|
|
|
|
240,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "frame", 0, 0, 0, 255, 0, { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "underlay",
|
|
|
|
104,
|
|
|
|
104,
|
|
|
|
110,
|
|
|
|
0,
|
|
|
|
104,
|
|
|
|
{ 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ "black", 0, 0, 0, 0, 0, { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 } },
|
|
|
|
{ 0 } };
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
typedef struct button_t {
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
char* name;
|
|
|
|
short pressed;
|
|
|
|
short extra;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int code;
|
|
|
|
int x, y;
|
|
|
|
unsigned int w, h;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int lc;
|
|
|
|
char* label;
|
|
|
|
short font_size;
|
|
|
|
unsigned int lw, lh;
|
|
|
|
unsigned char* lb;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
char* letter;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
char* left;
|
|
|
|
short is_menu;
|
|
|
|
char* right;
|
|
|
|
char* sub;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
Pixmap map;
|
|
|
|
Pixmap down;
|
|
|
|
Window xwin;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
} button_t;
|
2023-04-30 16:34:53 +02:00
|
|
|
#endif
|
|
|
|
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_SDL1 )
|
2023-04-30 16:34:53 +02:00
|
|
|
// Control how the screen update is performed: at regular intervals (delayed)
|
|
|
|
// or immediatly Note: this is only for the LCD. The annunciators and the
|
|
|
|
// buttons are always immediately updated
|
2023-05-02 14:40:02 +02:00
|
|
|
// #define DELAYEDDISPUPDATE
|
2023-04-30 16:34:53 +02:00
|
|
|
// Interval in millisecond between screen updates
|
|
|
|
#define DISPUPDATEINTERVAL 200
|
|
|
|
|
|
|
|
color_t colors_sx[] = { { "white", 255, 255, 255 },
|
|
|
|
{ "left", 255, 166, 0 },
|
|
|
|
{ "right", 0, 210, 255 },
|
|
|
|
{ "but_top", 109, 93, 93 },
|
|
|
|
{ "button", 90, 77, 770 },
|
|
|
|
{ "but_bot", 76, 65, 65 },
|
|
|
|
{ "lcd_col", 202, 221, 92 },
|
|
|
|
{ "pix_col", 0, 0, 128 },
|
|
|
|
{ "pad_top", 109, 78, 78 },
|
|
|
|
{ "pad", 90, 64, 64 },
|
|
|
|
{ "pad_bot", 76, 54, 54 },
|
|
|
|
{ "disp_pad_top", 155, 118, 84 },
|
|
|
|
{ "disp_pad", 124, 94, 67 },
|
|
|
|
{ "disp_pad_bot", 100, 75, 53 },
|
|
|
|
{ "logo", 204, 169, 107 },
|
|
|
|
{ "logo_back", 64, 64, 64 },
|
|
|
|
{ "label", 202, 184, 144 },
|
|
|
|
{ "frame", 0, 0, 0 },
|
|
|
|
{ "underlay", 60, 42, 42 },
|
|
|
|
{ "black", 0, 0, 0 },
|
|
|
|
{ 0 } };
|
|
|
|
|
|
|
|
color_t colors_gx[] = { { "white", 255, 255, 255 },
|
|
|
|
{ "left", 255, 186, 255 },
|
|
|
|
{ "right", 0, 255, 204 },
|
|
|
|
{ "but_top", 104, 104, 104 },
|
|
|
|
{ "button", 88, 88, 88 },
|
|
|
|
{ "but_bot", 74, 74, 74 },
|
|
|
|
{ "lcd_col", 202, 221, 92 },
|
|
|
|
{ "pix_col", 0, 0, 128 },
|
|
|
|
{ "pad_top", 88, 88, 88 },
|
|
|
|
{ "pad", 74, 74, 74 },
|
|
|
|
{ "pad_bot", 64, 64, 64 },
|
|
|
|
{ "disp_pad_top", 128, 128, 138 },
|
|
|
|
{ "disp_pad", 104, 104, 110 },
|
|
|
|
{ "disp_pad_bot", 84, 84, 90 },
|
|
|
|
{ "logo", 176, 176, 184 },
|
|
|
|
{ "logo_back", 104, 104, 110 },
|
|
|
|
{ "label", 240, 240, 240 },
|
|
|
|
{ "frame", 0, 0, 0 },
|
|
|
|
{ "underlay", 104, 104, 110 },
|
|
|
|
{ "black", 0, 0, 0 },
|
|
|
|
{ 0 } };
|
|
|
|
|
|
|
|
unsigned int ARGBColors[ BLACK + 1 ];
|
|
|
|
#endif
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-30 16:34:53 +02:00
|
|
|
button_t* buttons = 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
button_t buttons_sx[] = {
|
2023-04-27 12:15:59 +02:00
|
|
|
{ "A",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x14,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"A",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "B",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x84,
|
|
|
|
50,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"B",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "C",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x83,
|
|
|
|
100,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"C",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "D",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x82,
|
|
|
|
150,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"D",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "E",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x81,
|
|
|
|
200,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"E",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "F",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x80,
|
|
|
|
250,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"F",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
|
|
|
|
{ "MTH", 0, 0, 0x24, 0, 50, 36, 26, WHITE, "MTH",
|
|
|
|
0, 0, 0, 0, "G", "PRINT", 1, 0, 0, 0 },
|
|
|
|
{ "PRG", 0, 0, 0x74, 50, 50, 36, 26, WHITE, "PRG",
|
|
|
|
0, 0, 0, 0, "H", "I/O", 1, 0, 0, 0 },
|
|
|
|
{ "CST", 0, 0, 0x73, 100, 50, 36, 26, WHITE, "CST",
|
|
|
|
0, 0, 0, 0, "I", "MODES", 1, 0, 0, 0 },
|
|
|
|
{ "VAR", 0, 0, 0x72, 150, 50, 36, 26, WHITE, "VAR",
|
|
|
|
0, 0, 0, 0, "J", "MEMORY", 1, 0, 0, 0 },
|
|
|
|
{ "UP", 0, 0, 0x71, 200, 50, 36, 26, WHITE, 0,
|
|
|
|
0, up_width, up_height, up_bits, "K", "LIBRARY", 1, 0, 0, 0 },
|
|
|
|
{ "NXT", 0, 0, 0x70, 250, 50, 36, 26, WHITE, "NXT",
|
|
|
|
0, 0, 0, 0, "L", "PREV", 0, 0, 0, 0 },
|
|
|
|
|
|
|
|
{ "COLON", 0, 0, 0x04, 0, 100, 36, 26, WHITE,
|
|
|
|
0, 0, colon_width, colon_height, colon_bits, "M", "UP", 0, "HOME",
|
|
|
|
0, 0 },
|
|
|
|
{ "STO", 0, 0, 0x64, 50, 100, 36, 26, WHITE, "STO",
|
|
|
|
0, 0, 0, 0, "N", "DEF", 0, "RCL", 0, 0 },
|
|
|
|
{ "EVAL", 0, 0, 0x63, 100, 100, 36, 26, WHITE, "EVAL",
|
|
|
|
0, 0, 0, 0, "O", "aQ", 0, "aNUM", 0, 0 },
|
|
|
|
{ "LEFT", 0, 0, 0x62, 150, 100, 36, 26,
|
|
|
|
WHITE, 0, 0, left_width, left_height, left_bits, "P", "GRAPH",
|
|
|
|
0, 0, 0, 0 },
|
|
|
|
{ "DOWN", 0, 0, 0x61, 200, 100, 36, 26,
|
|
|
|
WHITE, 0, 0, down_width, down_height, down_bits, "Q", "REVIEW",
|
|
|
|
0, 0, 0, 0 },
|
|
|
|
{ "RIGHT", 0, 0, 0x60, 250, 100, 36, 26, WHITE,
|
|
|
|
0, 0, right_width, right_height, right_bits, "R", "SWAP", 0, 0,
|
|
|
|
0, 0 },
|
|
|
|
|
|
|
|
{ "SIN", 0, 0, 0x34, 0, 150, 36, 26, WHITE, "SIN",
|
|
|
|
0, 0, 0, 0, "S", "ASIN", 0, "b", 0, 0 },
|
|
|
|
{ "COS", 0, 0, 0x54, 50, 150, 36, 26, WHITE, "COS",
|
|
|
|
0, 0, 0, 0, "T", "ACOS", 0, "c", 0, 0 },
|
|
|
|
{ "TAN", 0, 0, 0x53, 100, 150, 36, 26, WHITE, "TAN",
|
|
|
|
0, 0, 0, 0, "U", "ATAN", 0, "d", 0, 0 },
|
|
|
|
{ "SQRT", 0, 0, 0x52, 150, 150, 36, 26, WHITE, 0,
|
|
|
|
0, sqrt_width, sqrt_height, sqrt_bits, "V", "e", 0, "f", 0, 0 },
|
|
|
|
{ "POWER", 0, 0, 0x51, 200, 150, 36, 26, WHITE,
|
|
|
|
0, 0, power_width, power_height, power_bits, "W", "g", 0, "LOG",
|
|
|
|
0, 0 },
|
|
|
|
{ "INV", 0, 0, 0x50, 250, 150, 36, 26, WHITE, 0,
|
|
|
|
0, inv_width, inv_height, inv_bits, "X", "h", 0, "LN", 0, 0 },
|
|
|
|
|
|
|
|
{ "ENTER", 0, 0, 0x44, 0, 200, 86, 26, WHITE, "ENTER",
|
|
|
|
2, 0, 0, 0, 0, "EQUATION", 0, "MATRIX", 0, 0 },
|
|
|
|
{ "NEG", 0, 0, 0x43, 100, 200, 36,
|
|
|
|
26, WHITE, 0, 0, neg_width, neg_height, neg_bits,
|
|
|
|
"Y", "EDIT", 0, "VISIT", 0, 0 },
|
|
|
|
{ "EEX", 0, 0, 0x42, 150, 200, 36, 26, WHITE, "EEX",
|
|
|
|
0, 0, 0, 0, "Z", "2D", 0, "3D", 0, 0 },
|
|
|
|
{ "DEL", 0, 0, 0x41, 200, 200, 36, 26, WHITE, "DEL",
|
|
|
|
0, 0, 0, 0, 0, "PURGE", 0, 0, 0, 0 },
|
|
|
|
{ "BS", 0, 0, 0x40, 250, 200, 36, 26, WHITE, 0,
|
|
|
|
0, bs_width, bs_height, bs_bits, 0, "DROP", 0, "CLR", 0, 0 },
|
|
|
|
|
|
|
|
{ "ALPHA",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x35,
|
|
|
|
0,
|
|
|
|
250,
|
|
|
|
36,
|
|
|
|
26,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
alpha_width,
|
|
|
|
alpha_height,
|
|
|
|
alpha_bits,
|
|
|
|
0,
|
|
|
|
"USR",
|
|
|
|
0,
|
|
|
|
"ENTRY",
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "7", 0, 0, 0x33, 60, 250, 46, 26, WHITE, "7",
|
|
|
|
1, 0, 0, 0, 0, "SOLVE", 1, 0, 0, 0 },
|
|
|
|
{ "8", 0, 0, 0x32, 120, 250, 46, 26, WHITE, "8",
|
|
|
|
1, 0, 0, 0, 0, "PLOT", 1, 0, 0, 0 },
|
|
|
|
{ "9", 0, 0, 0x31, 180, 250, 46, 26, WHITE, "9",
|
|
|
|
1, 0, 0, 0, 0, "ALGEBRA", 1, 0, 0, 0 },
|
|
|
|
{ "DIV", 0, 0, 0x30, 240, 250, 46, 26, WHITE, 0,
|
|
|
|
0, div_width, div_height, div_bits, 0, "( )", 0, "#", 0, 0 },
|
|
|
|
|
|
|
|
{ "SHL", 0, 0, 0x25, 0, 300, 36, 26, LEFT, 0,
|
|
|
|
0, shl_width, shl_height, shl_bits, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ "4", 0, 0, 0x23, 60, 300, 46, 26, WHITE, "4",
|
|
|
|
1, 0, 0, 0, 0, "TIME", 1, 0, 0, 0 },
|
|
|
|
{ "5", 0, 0, 0x22, 120, 300, 46, 26, WHITE, "5",
|
|
|
|
1, 0, 0, 0, 0, "STAT", 1, 0, 0, 0 },
|
|
|
|
{ "6", 0, 0, 0x21, 180, 300, 46, 26, WHITE, "6",
|
|
|
|
1, 0, 0, 0, 0, "UNITS", 1, 0, 0, 0 },
|
|
|
|
{ "MUL", 0, 0, 0x20, 240, 300, 46, 26, WHITE, 0,
|
|
|
|
0, mul_width, mul_height, mul_bits, 0, "[ ]", 0, "_", 0, 0 },
|
|
|
|
|
|
|
|
{ "SHR", 0, 0, 0x15, 0, 350, 36, 26, RIGHT, 0,
|
|
|
|
0, shr_width, shr_height, shr_bits, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ "1", 0, 0, 0x13, 60, 350, 46, 26, WHITE, "1",
|
|
|
|
1, 0, 0, 0, 0, "RAD", 0, "POLAR", 0, 0 },
|
|
|
|
{ "2", 0, 0, 0x12, 120, 350, 46, 26, WHITE, "2",
|
|
|
|
1, 0, 0, 0, 0, "STACK", 0, "ARG", 0, 0 },
|
|
|
|
{ "3", 0, 0, 0x11, 180, 350, 46, 26, WHITE, "3",
|
|
|
|
1, 0, 0, 0, 0, "CMD", 0, "MENU", 0, 0 },
|
|
|
|
{ "MINUS", 0, 0, 0x10, 240, 350, 46, 26, WHITE,
|
|
|
|
0, 0, minus_width, minus_height, minus_bits, 0, "i", 0, "j",
|
|
|
|
0, 0 },
|
|
|
|
|
|
|
|
{ "ON", 0, 0, 0x8000, 0, 400, 36, 26, WHITE, "ON",
|
|
|
|
0, 0, 0, 0, 0, "CONT", 0, "OFF", "ATTN", 0 },
|
|
|
|
{ "0", 0, 0, 0x03, 60, 400, 46, 26, WHITE, "0",
|
|
|
|
1, 0, 0, 0, 0, "= ", 0, " a", 0, 0 },
|
|
|
|
{ "PERIOD", 0, 0, 0x02, 120, 400, 46, 26, WHITE, ".",
|
|
|
|
1, 0, 0, 0, 0, ", ", 0, " k", 0, 0 },
|
|
|
|
{ "SPC", 0, 0, 0x01, 180, 400, 46, 26, WHITE, "SPC",
|
|
|
|
0, 0, 0, 0, 0, "l ", 0, " m", 0, 0 },
|
|
|
|
{ "PLUS", 0, 0, 0x00, 240, 400, 46, 26,
|
|
|
|
WHITE, 0, 0, plus_width, plus_height, plus_bits, 0, "{ }",
|
|
|
|
0, ": :", 0, 0 },
|
|
|
|
|
|
|
|
{ 0 } };
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
button_t buttons_gx[] = {
|
2023-04-27 12:15:59 +02:00
|
|
|
{ "A",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x14,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"A",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "B",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x84,
|
|
|
|
50,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"B",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "C",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x83,
|
|
|
|
100,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"C",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "D",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x82,
|
|
|
|
150,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"D",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "E",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x81,
|
|
|
|
200,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"E",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "F",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x80,
|
|
|
|
250,
|
|
|
|
0,
|
|
|
|
36,
|
|
|
|
23,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
menu_label_width,
|
|
|
|
menu_label_height,
|
|
|
|
menu_label_bits,
|
|
|
|
"F",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
|
|
|
|
{ "MTH", 0, 0, 0x24, 0, 50, 36, 26, WHITE, "MTH",
|
|
|
|
0, 0, 0, 0, "G", "RAD", 0, "POLAR", 0, 0 },
|
|
|
|
{ "PRG", 0, 0, 0x74, 50, 50, 36, 26, WHITE, "PRG",
|
|
|
|
0, 0, 0, 0, "H", 0, 0, "CHARS", 0, 0 },
|
|
|
|
{ "CST", 0, 0, 0x73, 100, 50, 36, 26, WHITE, "CST",
|
|
|
|
0, 0, 0, 0, "I", 0, 0, "MODES", 0, 0 },
|
|
|
|
{ "VAR", 0, 0, 0x72, 150, 50, 36, 26, WHITE, "VAR",
|
|
|
|
0, 0, 0, 0, "J", 0, 0, "MEMORY", 0, 0 },
|
|
|
|
{ "UP", 0, 0, 0x71, 200, 50, 36, 26, WHITE, 0,
|
|
|
|
0, up_width, up_height, up_bits, "K", 0, 0, "STACK", 0, 0 },
|
|
|
|
{ "NXT", 0, 0, 0x70, 250, 50, 36, 26, WHITE, "NXT",
|
|
|
|
0, 0, 0, 0, "L", "PREV", 0, "MENU", 0, 0 },
|
|
|
|
|
|
|
|
{ "COLON", 0, 0, 0x04, 0, 100, 36, 26, WHITE,
|
|
|
|
0, 0, colon_width, colon_height, colon_bits, "M", "UP", 0, "HOME",
|
|
|
|
0, 0 },
|
|
|
|
{ "STO", 0, 0, 0x64, 50, 100, 36, 26, WHITE, "STO",
|
|
|
|
0, 0, 0, 0, "N", "DEF", 0, "RCL", 0, 0 },
|
|
|
|
{ "EVAL", 0, 0, 0x63, 100, 100, 36, 26, WHITE, "EVAL",
|
|
|
|
0, 0, 0, 0, "O", "aNUM", 0, "UNDO", 0, 0 },
|
|
|
|
{ "LEFT", 0, 0, 0x62, 150, 100, 36, 26,
|
|
|
|
WHITE, 0, 0, left_width, left_height, left_bits, "P", "PICTURE",
|
|
|
|
0, 0, 0, 0 },
|
|
|
|
{ "DOWN", 0, 0, 0x61, 200, 100, 36, 26,
|
|
|
|
WHITE, 0, 0, down_width, down_height, down_bits, "Q", "VIEW",
|
|
|
|
0, 0, 0, 0 },
|
|
|
|
{ "RIGHT", 0, 0, 0x60, 250, 100, 36, 26, WHITE,
|
|
|
|
0, 0, right_width, right_height, right_bits, "R", "SWAP", 0, 0,
|
|
|
|
0, 0 },
|
|
|
|
|
|
|
|
{ "SIN", 0, 0, 0x34, 0, 150, 36, 26, WHITE, "SIN",
|
|
|
|
0, 0, 0, 0, "S", "ASIN", 0, "b", 0, 0 },
|
|
|
|
{ "COS", 0, 0, 0x54, 50, 150, 36, 26, WHITE, "COS",
|
|
|
|
0, 0, 0, 0, "T", "ACOS", 0, "c", 0, 0 },
|
|
|
|
{ "TAN", 0, 0, 0x53, 100, 150, 36, 26, WHITE, "TAN",
|
|
|
|
0, 0, 0, 0, "U", "ATAN", 0, "d", 0, 0 },
|
|
|
|
{ "SQRT", 0, 0, 0x52, 150, 150, 36, 26, WHITE, 0,
|
|
|
|
0, sqrt_width, sqrt_height, sqrt_bits, "V", "n", 0, "o", 0, 0 },
|
|
|
|
{ "POWER", 0, 0, 0x51, 200, 150, 36, 26, WHITE,
|
|
|
|
0, 0, power_width, power_height, power_bits, "W", "p", 0, "LOG",
|
|
|
|
0, 0 },
|
|
|
|
{ "INV", 0, 0, 0x50, 250, 150, 36, 26, WHITE, 0,
|
|
|
|
0, inv_width, inv_height, inv_bits, "X", "q", 0, "LN", 0, 0 },
|
|
|
|
|
|
|
|
{ "ENTER", 0, 0, 0x44, 0, 200, 86, 26, WHITE, "ENTER",
|
|
|
|
2, 0, 0, 0, 0, "EQUATION", 0, "MATRIX", 0, 0 },
|
|
|
|
{ "NEG", 0, 0, 0x43, 100, 200, 36,
|
|
|
|
26, WHITE, 0, 0, neg_width, neg_height, neg_bits,
|
|
|
|
"Y", "EDIT", 0, "CMD", 0, 0 },
|
|
|
|
{ "EEX", 0, 0, 0x42, 150, 200, 36, 26, WHITE, "EEX",
|
|
|
|
0, 0, 0, 0, "Z", "PURG", 0, "ARG", 0, 0 },
|
|
|
|
{ "DEL", 0, 0, 0x41, 200, 200, 36, 26, WHITE, "DEL",
|
|
|
|
0, 0, 0, 0, 0, "CLEAR", 0, 0, 0, 0 },
|
|
|
|
{ "BS", 0, 0, 0x40, 250, 200, 36, 26, WHITE, 0,
|
|
|
|
0, bs_width, bs_height, bs_bits, 0, "DROP", 0, 0, 0, 0 },
|
|
|
|
|
|
|
|
{ "ALPHA",
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0x35,
|
|
|
|
0,
|
|
|
|
250,
|
|
|
|
36,
|
|
|
|
26,
|
|
|
|
WHITE,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
alpha_width,
|
|
|
|
alpha_height,
|
|
|
|
alpha_bits,
|
|
|
|
0,
|
|
|
|
"USER",
|
|
|
|
0,
|
|
|
|
"ENTRY",
|
|
|
|
0,
|
|
|
|
0 },
|
|
|
|
{ "7", 0, 0, 0x33, 60, 250, 46, 26, WHITE, "7",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "SOLVE", 0, 0 },
|
|
|
|
{ "8", 0, 0, 0x32, 120, 250, 46, 26, WHITE, "8",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "PLOT", 0, 0 },
|
|
|
|
{ "9", 0, 0, 0x31, 180, 250, 46, 26, WHITE, "9",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "SYMBOLIC", 0, 0 },
|
|
|
|
{ "DIV", 0, 0, 0x30, 240, 250, 46, 26, WHITE, 0,
|
|
|
|
0, div_width, div_height, div_bits, 0, "r ", 0, "s", 0, 0 },
|
|
|
|
|
|
|
|
{ "SHL", 0, 0, 0x25, 0, 300, 36, 26, LEFT, 0,
|
|
|
|
0, shl_width, shl_height, shl_bits, 0, 0, 0, 0, 0, 0 },
|
|
|
|
{ "4", 0, 0, 0x23, 60, 300, 46, 26, WHITE, "4",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "TIME", 0, 0 },
|
|
|
|
{ "5", 0, 0, 0x22, 120, 300, 46, 26, WHITE, "5",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "STAT", 0, 0 },
|
|
|
|
{ "6", 0, 0, 0x21, 180, 300, 46, 26, WHITE, "6",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "UNITS", 0, 0 },
|
|
|
|
{ "MUL", 0, 0, 0x20, 240, 300, 46, 26, WHITE, 0,
|
|
|
|
0, mul_width, mul_height, mul_bits, 0, "t ", 0, "u", 0, 0 },
|
|
|
|
|
|
|
|
{ "SHR", 0, 0, 0x15, 0, 350, 36, 26, RIGHT, 0,
|
|
|
|
0, shr_width, shr_height, shr_bits, 0, 0, 1, " ", 0, 0 },
|
|
|
|
{ "1", 0, 0, 0x13, 60, 350, 46, 26, WHITE, "1",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "I/O", 0, 0 },
|
|
|
|
{ "2", 0, 0, 0x12, 120, 350, 46, 26, WHITE, "2",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "LIBRARY", 0, 0 },
|
|
|
|
{ "3", 0, 0, 0x11, 180, 350, 46, 26, WHITE, "3",
|
|
|
|
1, 0, 0, 0, 0, 0, 1, "EQ LIB", 0, 0 },
|
|
|
|
{ "MINUS", 0, 0, 0x10, 240, 350, 46, 26, WHITE,
|
|
|
|
0, 0, minus_width, minus_height, minus_bits, 0, "v ", 0, "w",
|
|
|
|
0, 0 },
|
|
|
|
|
|
|
|
{ "ON", 0, 0, 0x8000, 0, 400, 36, 26, WHITE, "ON",
|
|
|
|
0, 0, 0, 0, 0, "CONT", 0, "OFF", "CANCEL", 0 },
|
|
|
|
{ "0", 0, 0, 0x03, 60, 400, 46, 26, WHITE, "0",
|
|
|
|
1, 0, 0, 0, 0, "\004 ", 0, "\003", 0, 0 },
|
|
|
|
{ "PERIOD", 0, 0, 0x02, 120, 400, 46, 26, WHITE, ".",
|
|
|
|
1, 0, 0, 0, 0, "\002 ", 0, "\001", 0, 0 },
|
|
|
|
{ "SPC", 0, 0, 0x01, 180, 400, 46, 26, WHITE, "SPC",
|
|
|
|
0, 0, 0, 0, 0, "\005 ", 0, "z", 0, 0 },
|
|
|
|
{ "PLUS", 0, 0, 0x00, 240, 400, 46, 26, WHITE, 0, 0,
|
|
|
|
plus_width, plus_height, plus_bits, 0, "x ", 0, "y", 0, 0 },
|
|
|
|
|
|
|
|
{ 0 } };
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_X11 )
|
2015-07-26 11:16:05 +02:00
|
|
|
typedef struct icon_t {
|
2023-04-27 12:15:59 +02:00
|
|
|
unsigned int w;
|
|
|
|
unsigned int h;
|
|
|
|
int c;
|
|
|
|
unsigned char* bits;
|
2015-07-26 11:16:05 +02:00
|
|
|
} icon_map_t;
|
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
#define ICON_MAP 0
|
|
|
|
#define ON_MAP 1
|
|
|
|
#define DISP_MAP 2
|
2015-07-26 11:16:05 +02:00
|
|
|
#define FIRST_MAP 3
|
2022-03-24 13:41:22 +01:00
|
|
|
#define LAST_MAP 9
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
icon_map_t* icon_maps;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
icon_map_t icon_maps_sx[] = {
|
2023-04-27 12:15:59 +02:00
|
|
|
{ hp48_icon_width, hp48_icon_height, BLACK, hp48_icon_bits },
|
|
|
|
{ hp48_on_width, hp48_on_height, PIXEL, hp48_on_bits },
|
|
|
|
{ hp48_disp_width, hp48_disp_height, LCD, hp48_disp_bits },
|
|
|
|
{ hp48_top_width, hp48_top_height, DISP_PAD, hp48_top_bits },
|
|
|
|
{ hp48_bottom_width, hp48_bottom_height, PAD, hp48_bottom_bits },
|
|
|
|
{ hp48_logo_width, hp48_logo_height, LOGO, hp48_logo_bits },
|
|
|
|
{ hp48_text_width, hp48_text_height, LABEL, hp48_text_bits },
|
|
|
|
{ hp48_keys_width, hp48_keys_height, BLACK, hp48_keys_bits },
|
|
|
|
{ hp48_orange_width, hp48_orange_height, LEFT, hp48_orange_bits },
|
|
|
|
{ hp48_blue_width, hp48_blue_height, RIGHT, hp48_blue_bits } };
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
icon_map_t icon_maps_gx[] = {
|
2023-04-27 12:15:59 +02:00
|
|
|
{ hp48_icon_width, hp48_icon_height, BLACK, hp48_icon_bits },
|
|
|
|
{ hp48_on_width, hp48_on_height, PIXEL, hp48_on_bits },
|
|
|
|
{ hp48_disp_width, hp48_disp_height, LCD, hp48_disp_bits },
|
|
|
|
{ hp48_top_gx_width, hp48_top_gx_height, DISP_PAD, hp48_top_gx_bits },
|
|
|
|
{ hp48_bottom_width, hp48_bottom_height, PAD, hp48_bottom_bits },
|
|
|
|
{ hp48_logo_gx_width, hp48_logo_gx_height, LOGO, hp48_logo_gx_bits },
|
|
|
|
{ hp48_text_gx_width, hp48_text_gx_height, LABEL, hp48_text_gx_bits },
|
|
|
|
{ hp48_keys_width, hp48_keys_height, BLACK, hp48_keys_bits },
|
|
|
|
{ hp48_orange_width, hp48_orange_height, LEFT, hp48_orange_bits },
|
|
|
|
{ hp48_green_gx_width, hp48_green_gx_height, RIGHT, hp48_green_gx_bits } };
|
|
|
|
|
|
|
|
#define KEYBOARD_HEIGHT ( buttons[ LAST_BUTTON ].y + buttons[ LAST_BUTTON ].h )
|
|
|
|
#define KEYBOARD_WIDTH ( buttons[ LAST_BUTTON ].x + buttons[ LAST_BUTTON ].w )
|
2022-03-24 13:41:22 +01:00
|
|
|
|
|
|
|
#define TOP_SKIP 65
|
|
|
|
#define SIDE_SKIP 20
|
|
|
|
#define BOTTOM_SKIP 25
|
|
|
|
#define DISP_KBD_SKIP 65
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
#define DISPLAY_WIDTH ( 264 + 8 )
|
|
|
|
#define DISPLAY_HEIGHT ( 128 + 16 + 8 )
|
|
|
|
#define DISPLAY_OFFSET_X ( SIDE_SKIP + ( 286 - DISPLAY_WIDTH ) / 2 )
|
2022-03-24 13:41:22 +01:00
|
|
|
#define DISPLAY_OFFSET_Y TOP_SKIP
|
|
|
|
|
|
|
|
#define DISP_FRAME 8
|
|
|
|
|
|
|
|
#define KEYBOARD_OFFSET_X SIDE_SKIP
|
2023-04-27 12:15:59 +02:00
|
|
|
#define KEYBOARD_OFFSET_Y ( TOP_SKIP + DISPLAY_HEIGHT + DISP_KBD_SKIP )
|
|
|
|
|
|
|
|
int AllocColors( void ) {
|
|
|
|
int c, error, dyn;
|
|
|
|
int r_shift = 0, g_shift = 0, b_shift = 0;
|
|
|
|
XSetWindowAttributes xswa;
|
|
|
|
|
|
|
|
error = -1;
|
|
|
|
dyn = dynamic_color;
|
|
|
|
|
|
|
|
if ( direct_color ) {
|
|
|
|
while ( !( visual->red_mask & ( 1 << r_shift ) ) )
|
|
|
|
r_shift++;
|
|
|
|
while ( visual->red_mask & ( 1 << r_shift ) )
|
|
|
|
r_shift++;
|
|
|
|
r_shift = 16 - r_shift;
|
|
|
|
while ( !( visual->green_mask & ( 1 << g_shift ) ) )
|
|
|
|
g_shift++;
|
|
|
|
while ( ( visual->green_mask & ( 1 << g_shift ) ) )
|
|
|
|
g_shift++;
|
|
|
|
g_shift = 16 - g_shift;
|
|
|
|
while ( !( visual->blue_mask & ( 1 << b_shift ) ) )
|
|
|
|
b_shift++;
|
|
|
|
while ( ( visual->blue_mask & ( 1 << b_shift ) ) )
|
|
|
|
b_shift++;
|
|
|
|
b_shift = 16 - b_shift;
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
for ( c = WHITE; c <= BLACK; c++ ) {
|
|
|
|
switch ( color_mode ) {
|
|
|
|
case COLOR_MODE_MONO:
|
|
|
|
colors[ c ].xcolor.red = colors[ c ].mono_rgb << 8;
|
|
|
|
colors[ c ].xcolor.green = colors[ c ].mono_rgb << 8;
|
|
|
|
colors[ c ].xcolor.blue = colors[ c ].mono_rgb << 8;
|
|
|
|
break;
|
|
|
|
case COLOR_MODE_GRAY:
|
|
|
|
colors[ c ].xcolor.red = colors[ c ].gray_rgb << 8;
|
|
|
|
colors[ c ].xcolor.green = colors[ c ].gray_rgb << 8;
|
|
|
|
colors[ c ].xcolor.blue = colors[ c ].gray_rgb << 8;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
colors[ c ].xcolor.red = colors[ c ].r << 8;
|
|
|
|
colors[ c ].xcolor.green = colors[ c ].g << 8;
|
|
|
|
colors[ c ].xcolor.blue = colors[ c ].b << 8;
|
|
|
|
break;
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( direct_color ) {
|
|
|
|
colors[ c ].xcolor.pixel =
|
|
|
|
( ( colors[ c ].xcolor.red >> r_shift ) & visual->red_mask ) |
|
|
|
|
( ( colors[ c ].xcolor.green >> g_shift ) &
|
|
|
|
visual->green_mask ) |
|
|
|
|
( ( colors[ c ].xcolor.blue >> b_shift ) & visual->blue_mask );
|
|
|
|
XStoreColor( dpy, cmap, &colors[ c ].xcolor );
|
|
|
|
} else {
|
|
|
|
if ( dynamic_color && c == PIXEL ) {
|
|
|
|
if ( XAllocColorCells( dpy, cmap, True, ( unsigned long* )0, 0,
|
|
|
|
&colors[ c ].xcolor.pixel, 1 ) == 0 ) {
|
|
|
|
dyn = 0;
|
|
|
|
if ( XAllocColor( dpy, cmap, &colors[ c ].xcolor ) == 0 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: XAllocColor failed.\n",
|
|
|
|
progname );
|
|
|
|
error = c;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if ( colors[ c ].xcolor.pixel >= visual->map_entries ) {
|
|
|
|
dyn = 0;
|
|
|
|
if ( XAllocColor( dpy, cmap, &colors[ c ].xcolor ) == 0 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: XAllocColor failed.\n",
|
|
|
|
progname );
|
|
|
|
error = c;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
XStoreColor( dpy, cmap, &colors[ c ].xcolor );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( XAllocColor( dpy, cmap, &colors[ c ].xcolor ) == 0 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: XAllocColor failed.\n",
|
|
|
|
progname );
|
|
|
|
error = c;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* Can't be reached when visual->class == DirectColor
|
2022-03-24 13:41:22 +01:00
|
|
|
*/
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( error != -1 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: Using own Colormap.\n", progname );
|
|
|
|
/*
|
|
|
|
* free colors so far allocated
|
|
|
|
*/
|
|
|
|
for ( c = WHITE; c < error; c++ ) {
|
|
|
|
XFreeColors( dpy, cmap, &colors[ c ].xcolor.pixel, 1, 0 );
|
|
|
|
}
|
2022-03-24 13:41:22 +01:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* Create my own Colormap
|
|
|
|
*/
|
|
|
|
cmap = XCreateColormap( dpy, mainW, visual, AllocNone );
|
|
|
|
if ( cmap == ( Colormap )0 ) {
|
|
|
|
sprintf( errbuf, "can\'t alloc Colormap.\n" );
|
2022-03-24 13:41:22 +01:00
|
|
|
fatal_exit();
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
xswa.colormap = cmap;
|
|
|
|
XChangeWindowAttributes( dpy, mainW, CWColormap, &xswa );
|
|
|
|
if ( iconW )
|
|
|
|
XChangeWindowAttributes( dpy, iconW, CWColormap, &xswa );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to allocate colors again
|
|
|
|
*/
|
|
|
|
dyn = dynamic_color;
|
|
|
|
for ( c = WHITE; c <= BLACK; c++ ) {
|
|
|
|
switch ( color_mode ) {
|
|
|
|
case COLOR_MODE_MONO:
|
|
|
|
colors[ c ].xcolor.red = colors[ c ].mono_rgb << 8;
|
|
|
|
colors[ c ].xcolor.green = colors[ c ].mono_rgb << 8;
|
|
|
|
colors[ c ].xcolor.blue = colors[ c ].mono_rgb << 8;
|
|
|
|
break;
|
|
|
|
case COLOR_MODE_GRAY:
|
|
|
|
colors[ c ].xcolor.red = colors[ c ].gray_rgb << 8;
|
|
|
|
colors[ c ].xcolor.green = colors[ c ].gray_rgb << 8;
|
|
|
|
colors[ c ].xcolor.blue = colors[ c ].gray_rgb << 8;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
colors[ c ].xcolor.red = colors[ c ].r << 8;
|
|
|
|
colors[ c ].xcolor.green = colors[ c ].g << 8;
|
|
|
|
colors[ c ].xcolor.blue = colors[ c ].b << 8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ( dynamic_color && c == PIXEL ) {
|
|
|
|
if ( XAllocColorCells( dpy, cmap, True, ( unsigned long* )0, 0,
|
|
|
|
&colors[ c ].xcolor.pixel, 1 ) == 0 ) {
|
|
|
|
dyn = 0;
|
|
|
|
if ( XAllocColor( dpy, cmap, &colors[ c ].xcolor ) == 0 ) {
|
|
|
|
sprintf( errbuf, "can\'t alloc Color.\n" );
|
|
|
|
fatal_exit();
|
|
|
|
}
|
|
|
|
} else if ( colors[ c ].xcolor.pixel >= visual->map_entries ) {
|
|
|
|
dyn = 0;
|
|
|
|
if ( XAllocColor( dpy, cmap, &colors[ c ].xcolor ) == 0 ) {
|
|
|
|
sprintf( errbuf, "can\'t alloc Color.\n" );
|
|
|
|
fatal_exit();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
XStoreColor( dpy, cmap, &colors[ c ].xcolor );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( XAllocColor( dpy, cmap, &colors[ c ].xcolor ) == 0 ) {
|
|
|
|
sprintf( errbuf, "can\'t alloc Color.\n" );
|
|
|
|
fatal_exit();
|
|
|
|
}
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
dynamic_color = dyn;
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void adjust_contrast( int contrast ) {
|
|
|
|
int gray = 0;
|
|
|
|
int r = 0, g = 0, b = 0;
|
|
|
|
unsigned long old;
|
|
|
|
|
|
|
|
if ( contrast < 0x3 )
|
|
|
|
contrast = 0x3;
|
|
|
|
if ( contrast > 0x13 )
|
|
|
|
contrast = 0x13;
|
|
|
|
|
|
|
|
old = colors[ PIXEL ].xcolor.pixel;
|
|
|
|
switch ( color_mode ) {
|
|
|
|
case COLOR_MODE_MONO:
|
|
|
|
return;
|
|
|
|
case COLOR_MODE_GRAY:
|
|
|
|
gray = ( 0x13 - contrast ) * ( colors[ LCD ].gray_rgb / 0x10 );
|
|
|
|
colors[ PIXEL ].xcolor.red = gray << 8;
|
|
|
|
colors[ PIXEL ].xcolor.green = gray << 8;
|
|
|
|
colors[ PIXEL ].xcolor.blue = gray << 8;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r = ( 0x13 - contrast ) * ( colors[ LCD ].r / 0x10 );
|
|
|
|
g = ( 0x13 - contrast ) * ( colors[ LCD ].g / 0x10 );
|
|
|
|
b = 128 -
|
|
|
|
( ( 0x13 - contrast ) * ( ( 128 - colors[ LCD ].b ) / 0x10 ) );
|
|
|
|
colors[ PIXEL ].xcolor.red = r << 8;
|
|
|
|
colors[ PIXEL ].xcolor.green = g << 8;
|
|
|
|
colors[ PIXEL ].xcolor.blue = b << 8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if ( direct_color ) {
|
|
|
|
colors[ PIXEL ].gray_rgb = gray;
|
|
|
|
colors[ PIXEL ].r = r;
|
|
|
|
colors[ PIXEL ].g = g;
|
|
|
|
colors[ PIXEL ].b = b;
|
|
|
|
AllocColors();
|
|
|
|
XSetForeground( dpy, disp.gc, COLOR( PIXEL ) );
|
2022-03-24 13:41:22 +01:00
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
disp.display_update = UPDATE_DISP | UPDATE_MENU;
|
|
|
|
refresh_display();
|
2022-03-24 13:41:22 +01:00
|
|
|
#else
|
2023-04-27 12:15:59 +02:00
|
|
|
redraw_display();
|
2022-03-24 13:41:22 +01:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
redraw_annunc();
|
|
|
|
last_icon_state = -1;
|
|
|
|
refresh_icon();
|
|
|
|
} else if ( dynamic_color ) {
|
|
|
|
XStoreColor( dpy, cmap, &colors[ PIXEL ].xcolor );
|
2022-03-24 13:41:22 +01:00
|
|
|
} else {
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( XAllocColor( dpy, cmap, &colors[ PIXEL ].xcolor ) == 0 ) {
|
|
|
|
colors[ PIXEL ].xcolor.pixel = old;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: warning: can\'t alloc new pixel color.\n",
|
|
|
|
progname );
|
|
|
|
} else {
|
|
|
|
XFreeColors( dpy, cmap, &old, 1, 0 );
|
|
|
|
XSetForeground( dpy, disp.gc, COLOR( PIXEL ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
disp.display_update = UPDATE_DISP | UPDATE_MENU;
|
|
|
|
refresh_display();
|
2015-07-26 11:16:05 +02:00
|
|
|
#else
|
2023-04-27 12:15:59 +02:00
|
|
|
redraw_display();
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
redraw_annunc();
|
|
|
|
last_icon_state = -1;
|
|
|
|
refresh_icon();
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int merge_app_defaults( char* path, XrmDatabase* db ) {
|
|
|
|
char file[ 1024 ];
|
|
|
|
XrmDatabase tmp;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( path == ( char* )0 )
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
sprintf( file, "%s/%s", path, res_class );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
tmp = XrmGetFileDatabase( file );
|
|
|
|
if ( tmp == ( XrmDatabase )0 )
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XrmMergeDatabases( tmp, db );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int InitDisplay( int argc, char** argv ) {
|
|
|
|
XrmDatabase cmd = NULL, tmp = NULL;
|
|
|
|
char *res, *s;
|
|
|
|
char buf[ 1024 ], home[ 1024 ];
|
|
|
|
int def, i;
|
|
|
|
struct passwd* pwd;
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef SYSV
|
2023-04-27 12:15:59 +02:00
|
|
|
struct utsname uts;
|
2015-07-26 11:16:05 +02:00
|
|
|
#else
|
2023-04-27 12:15:59 +02:00
|
|
|
char hostname[ 128 ];
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* Parse the command line
|
|
|
|
*/
|
|
|
|
XrmInitialize();
|
|
|
|
XrmParseCommand( &cmd, options, sizeof( options ) / sizeof( *options ),
|
|
|
|
progname, &argc, argv );
|
|
|
|
|
|
|
|
if ( ( argc == 2 ) && !strcmp( argv[ 1 ], "-help" ) )
|
|
|
|
usage();
|
|
|
|
else if ( argc > 1 ) {
|
|
|
|
fprintf( stderr, "%s: unknown option %s or missing argument\n",
|
|
|
|
progname, argv[ 1 ] );
|
|
|
|
usage();
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
res_name = progname;
|
|
|
|
res_class = strdup( res_name );
|
|
|
|
*res_class = islower( *res_class ) ? _toupper( *res_class ) : *res_class;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* look for argument -name
|
|
|
|
*/
|
|
|
|
res = get_string_resource_from_db( cmd, "name", "Name" );
|
|
|
|
if ( res ) {
|
|
|
|
if ( !( res_name = strdup( res ) ) ) {
|
|
|
|
sprintf( errbuf, "out of memory in InitDisplay()\n" );
|
|
|
|
fatal_exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( s = res_name; *s; s++ )
|
|
|
|
*s = isupper( *s ) ? _tolower( *s ) : *s;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
free( res_class );
|
|
|
|
res_class = strdup( res_name );
|
|
|
|
*res_class =
|
|
|
|
islower( *res_class ) ? _toupper( *res_class ) : *res_class;
|
|
|
|
|
|
|
|
argc = saved_argc;
|
|
|
|
argv = ( char** )malloc( ( argc + 1 ) * sizeof( char* ) );
|
|
|
|
if ( argv == ( char** )0 ) {
|
|
|
|
sprintf( errbuf, "out of memory in InitDisplay()\n" );
|
|
|
|
fatal_exit();
|
|
|
|
}
|
|
|
|
argv[ argc ] = ( char* )0;
|
|
|
|
for ( i = 0; i < argc; i++ )
|
|
|
|
argv[ i ] = saved_argv[ i ];
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XrmParseCommand( &cmd, options, sizeof( options ) / sizeof( *options ),
|
|
|
|
res_name, &argc, argv );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Open the display
|
|
|
|
*/
|
|
|
|
res = get_string_resource_from_db( cmd, "display", "Display" );
|
|
|
|
|
|
|
|
dpy = XOpenDisplay( res );
|
|
|
|
if ( dpy == ( Display* )0 ) {
|
|
|
|
if ( res ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t open display %s\n", progname,
|
|
|
|
res );
|
|
|
|
} else {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: can\'t open display\n", progname );
|
|
|
|
}
|
|
|
|
return -1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Load all those Resources.
|
|
|
|
*
|
|
|
|
* 1. Hardcoded Defaults
|
|
|
|
*
|
2023-05-02 14:40:02 +02:00
|
|
|
* 2. /usr/lib/X11/app-defaults/X48NG
|
2023-04-27 12:15:59 +02:00
|
|
|
*
|
2023-05-02 14:40:02 +02:00
|
|
|
* 3. Values in $XUSERFILESEARCHPATH/X48NG or, if not set,
|
|
|
|
* $XAPPLRESDIR/X48NG
|
2023-04-27 12:15:59 +02:00
|
|
|
*
|
|
|
|
* 4. Values from XResourceManagerString() or, if empty,
|
|
|
|
* ~/.Xdefaults
|
|
|
|
*
|
|
|
|
* 5. Values in $XENVIRONMENT or, if not set,
|
|
|
|
* ~/.Xdefaults-hostname
|
|
|
|
*
|
|
|
|
* 6. Command line arguments
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* 1. Hardcoded Defaults */
|
|
|
|
|
|
|
|
for ( def = 0; defaults[ def ]; def++ ) {
|
|
|
|
if ( ( tmp = XrmGetStringDatabase( defaults[ def ] ) ) )
|
|
|
|
XrmMergeDatabases( tmp, &rdb );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-02 14:40:02 +02:00
|
|
|
/* 2. /usr/lib/X11/app-defaults/X48NG */
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
merge_app_defaults( "/usr/lib/X11/app-defaults", &rdb );
|
|
|
|
|
2023-05-02 14:40:02 +02:00
|
|
|
/* 3. Values in $XUSERFILESEARCHPATH/X48NG, or $XAPPLRESDIR/X48NG */
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
if ( !merge_app_defaults( getenv( "XUSERFILESEARCHPATH" ), &rdb ) )
|
|
|
|
merge_app_defaults( getenv( "XAPPLRESDIR" ), &rdb );
|
|
|
|
|
|
|
|
/* 4. Values from XResourceManagerString() or ~/.Xdefaults */
|
|
|
|
|
|
|
|
res = XResourceManagerString( dpy );
|
|
|
|
if ( res ) {
|
|
|
|
if ( ( tmp = XrmGetStringDatabase( res ) ) )
|
|
|
|
XrmMergeDatabases( tmp, &rdb );
|
|
|
|
} else {
|
|
|
|
res = getenv( "HOME" );
|
|
|
|
if ( res )
|
|
|
|
strcpy( home, res );
|
|
|
|
else {
|
|
|
|
pwd = getpwuid( getuid() );
|
|
|
|
if ( pwd )
|
|
|
|
strcpy( home, pwd->pw_dir );
|
|
|
|
}
|
|
|
|
sprintf( buf, "%s/.Xdefaults", home );
|
|
|
|
if ( ( tmp = XrmGetFileDatabase( buf ) ) )
|
|
|
|
XrmMergeDatabases( tmp, &rdb );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
/* 5. Values in $XENVIRONMENT or ~/.Xdefaults-hostname */
|
|
|
|
|
|
|
|
res = getenv( "XENVIRONMENT" );
|
|
|
|
if ( res ) {
|
|
|
|
if ( ( tmp = XrmGetFileDatabase( res ) ) )
|
|
|
|
XrmMergeDatabases( tmp, &rdb );
|
|
|
|
} else {
|
|
|
|
res = getenv( "HOME" );
|
|
|
|
if ( res )
|
|
|
|
strcpy( home, res );
|
|
|
|
else {
|
|
|
|
pwd = getpwuid( getuid() );
|
|
|
|
if ( pwd )
|
|
|
|
strcpy( home, pwd->pw_dir );
|
|
|
|
}
|
|
|
|
tmp = ( XrmDatabase )0;
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef SYSV
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( uname( &uts ) >= 0 ) {
|
|
|
|
sprintf( buf, "%s/.Xdefaults-%s", home, uts.nodename );
|
|
|
|
tmp = XrmGetFileDatabase( buf );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
#else
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( gethostname( hostname, 128 ) >= 0 ) {
|
|
|
|
sprintf( buf, "%s/.Xdefaults-%s", home, hostname );
|
|
|
|
tmp = XrmGetFileDatabase( buf );
|
|
|
|
}
|
2022-03-24 13:41:22 +01:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( tmp )
|
|
|
|
XrmMergeDatabases( tmp, &rdb );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/* 6. Command line arguments */
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( cmd )
|
|
|
|
XrmMergeDatabases( cmd, &rdb );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
get_resources();
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* Get the default screen
|
|
|
|
*/
|
|
|
|
screen = DefaultScreen( dpy );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* Does the Xserver do backing-store?
|
|
|
|
*/
|
|
|
|
does_backing_store = XDoesBackingStore( XScreenOfDisplay( dpy, screen ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef DEBUG_BACKING_STORE
|
2023-04-27 12:15:59 +02:00
|
|
|
fprintf( stderr, "XServer does%sBackingStore\n",
|
|
|
|
does_backing_store ? " " : " not do " );
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* Try to use XShm-Extension
|
|
|
|
*/
|
|
|
|
shm_flag = useXShm;
|
|
|
|
|
|
|
|
if ( !XShmQueryExtension( dpy ) ) {
|
|
|
|
shm_flag = 0;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: Xserver does not support XShm extension.\n",
|
|
|
|
progname );
|
|
|
|
}
|
|
|
|
if ( shm_flag )
|
|
|
|
fprintf( stderr, "%s: using XShm extension.\n", progname );
|
2015-07-26 11:16:05 +02:00
|
|
|
#else
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( useXShm ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: not compiled to use XShm extension.\n",
|
|
|
|
progname );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
#endif
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_SDL1 )
|
2023-04-30 16:34:53 +02:00
|
|
|
typedef struct sdltohpkeymap_t {
|
|
|
|
SDLKey sdlkey;
|
|
|
|
int hpkey;
|
|
|
|
} sdltohpkeymap_t;
|
|
|
|
|
|
|
|
sdltohpkeymap_t sdltohpkeymap[] = {
|
|
|
|
// Numbers
|
|
|
|
{ SDLK_0, BUTTON_0 },
|
|
|
|
{ SDLK_1, BUTTON_1 },
|
|
|
|
{ SDLK_2, BUTTON_2 },
|
|
|
|
{ SDLK_3, BUTTON_3 },
|
|
|
|
{ SDLK_4, BUTTON_4 },
|
|
|
|
{ SDLK_5, BUTTON_5 },
|
|
|
|
{ SDLK_6, BUTTON_6 },
|
|
|
|
{ SDLK_7, BUTTON_7 },
|
|
|
|
{ SDLK_8, BUTTON_8 },
|
|
|
|
{ SDLK_9, BUTTON_9 },
|
|
|
|
{ SDLK_KP0, BUTTON_0 },
|
|
|
|
{ SDLK_KP1, BUTTON_1 },
|
|
|
|
{ SDLK_KP2, BUTTON_2 },
|
|
|
|
{ SDLK_KP3, BUTTON_3 },
|
|
|
|
{ SDLK_KP4, BUTTON_4 },
|
|
|
|
{ SDLK_KP5, BUTTON_5 },
|
|
|
|
{ SDLK_KP6, BUTTON_6 },
|
|
|
|
{ SDLK_KP7, BUTTON_7 },
|
|
|
|
{ SDLK_KP8, BUTTON_8 },
|
|
|
|
{ SDLK_KP9, BUTTON_9 },
|
|
|
|
// Letters, space, return, backspace, delete, period, arrows
|
|
|
|
{ SDLK_a, BUTTON_A },
|
|
|
|
{ SDLK_b, BUTTON_B },
|
|
|
|
{ SDLK_c, BUTTON_C },
|
|
|
|
{ SDLK_d, BUTTON_D },
|
|
|
|
{ SDLK_e, BUTTON_E },
|
|
|
|
{ SDLK_f, BUTTON_F },
|
|
|
|
{ SDLK_g, BUTTON_MTH },
|
|
|
|
{ SDLK_h, BUTTON_PRG },
|
|
|
|
{ SDLK_i, BUTTON_CST },
|
|
|
|
{ SDLK_j, BUTTON_VAR },
|
|
|
|
{ SDLK_k, BUTTON_UP },
|
|
|
|
{ SDLK_UP, BUTTON_UP },
|
|
|
|
{ SDLK_l, BUTTON_NXT },
|
|
|
|
{ SDLK_m, BUTTON_COLON },
|
|
|
|
{ SDLK_n, BUTTON_STO },
|
|
|
|
{ SDLK_o, BUTTON_EVAL },
|
|
|
|
{ SDLK_p, BUTTON_LEFT },
|
|
|
|
{ SDLK_LEFT, BUTTON_LEFT },
|
|
|
|
{ SDLK_q, BUTTON_DOWN },
|
|
|
|
{ SDLK_DOWN, BUTTON_DOWN },
|
|
|
|
{ SDLK_r, BUTTON_RIGHT },
|
|
|
|
{ SDLK_RIGHT, BUTTON_RIGHT },
|
|
|
|
{ SDLK_s, BUTTON_SIN },
|
|
|
|
{ SDLK_t, BUTTON_COS },
|
|
|
|
{ SDLK_u, BUTTON_TAN },
|
|
|
|
{ SDLK_v, BUTTON_SQRT },
|
|
|
|
{ SDLK_w, BUTTON_POWER },
|
|
|
|
{ SDLK_x, BUTTON_INV },
|
|
|
|
{ SDLK_y, BUTTON_NEG },
|
|
|
|
{ SDLK_z, BUTTON_EEX },
|
|
|
|
{ SDLK_SPACE, BUTTON_SPC },
|
|
|
|
{ SDLK_RETURN, BUTTON_ENTER },
|
|
|
|
{ SDLK_KP_ENTER, BUTTON_ENTER },
|
|
|
|
{ SDLK_BACKSPACE, BUTTON_BS },
|
|
|
|
{ SDLK_DELETE, BUTTON_DEL },
|
|
|
|
{ SDLK_PERIOD, BUTTON_PERIOD },
|
|
|
|
{ SDLK_KP_PERIOD, BUTTON_PERIOD },
|
|
|
|
// Math operators
|
|
|
|
{ SDLK_PLUS, BUTTON_PLUS },
|
|
|
|
{ SDLK_KP_PLUS, BUTTON_PLUS },
|
|
|
|
{ SDLK_MINUS, BUTTON_MINUS },
|
|
|
|
{ SDLK_KP_MINUS, BUTTON_MINUS },
|
|
|
|
{ SDLK_ASTERISK, BUTTON_MUL },
|
|
|
|
{ SDLK_KP_MULTIPLY, BUTTON_MUL },
|
|
|
|
{ SDLK_SLASH, BUTTON_DIV },
|
|
|
|
{ SDLK_KP_DIVIDE, BUTTON_DIV },
|
|
|
|
// on, shift, alpha
|
|
|
|
{ SDLK_ESCAPE, BUTTON_ON },
|
|
|
|
{ SDLK_LSHIFT, BUTTON_SHL },
|
|
|
|
{ SDLK_RSHIFT, BUTTON_SHL },
|
|
|
|
{ SDLK_LCTRL, BUTTON_SHR },
|
|
|
|
{ SDLK_RCTRL, BUTTON_SHR },
|
|
|
|
{ SDLK_LALT, BUTTON_ALPHA },
|
|
|
|
{ SDLK_RALT, BUTTON_ALPHA },
|
|
|
|
|
2023-05-02 14:40:02 +02:00
|
|
|
// end marker
|
2023-04-30 16:34:53 +02:00
|
|
|
{ ( SDLKey )0, ( SDLKey )0 } };
|
|
|
|
|
|
|
|
void adjust_contrast( int contrast ) {
|
|
|
|
SDLCreateColors();
|
|
|
|
SDLCreateAnnunc();
|
|
|
|
redraw_display();
|
|
|
|
}
|
|
|
|
#endif
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int SmallTextWidth( const char* string, unsigned int length ) {
|
|
|
|
int i, w;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
w = 0;
|
|
|
|
for ( i = 0; i < length; i++ ) {
|
|
|
|
if ( small_font[ ( int )string[ i ] ].h != 0 ) {
|
|
|
|
w += small_font[ ( int )string[ i ] ].w + 1;
|
|
|
|
} else {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "Unknown small letter 0x00%x\n",
|
|
|
|
( int )string[ i ] );
|
|
|
|
w += 5;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
return w;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-05-02 16:57:24 +02:00
|
|
|
#if defined( GUI_IS_X11 )
|
2023-04-27 12:15:59 +02:00
|
|
|
int DrawSmallString( Display* the_dpy, Drawable d, GC the_gc, int x, int y,
|
|
|
|
const char* string, unsigned int length ) {
|
|
|
|
int i;
|
|
|
|
Pixmap pix;
|
|
|
|
|
|
|
|
for ( i = 0; i < length; i++ ) {
|
|
|
|
if ( small_font[ ( int )string[ i ] ].h != 0 ) {
|
|
|
|
pix = XCreateBitmapFromData(
|
|
|
|
the_dpy, d, ( char* )small_font[ ( int )string[ i ] ].bits,
|
|
|
|
small_font[ ( int )string[ i ] ].w,
|
|
|
|
small_font[ ( int )string[ i ] ].h );
|
|
|
|
XCopyPlane( the_dpy, pix, d, the_gc, 0, 0,
|
|
|
|
small_font[ ( int )string[ i ] ].w,
|
|
|
|
small_font[ ( int )string[ i ] ].h, x,
|
|
|
|
( int )( y - small_font[ ( int )string[ i ] ].h ), 1 );
|
|
|
|
XFreePixmap( the_dpy, pix );
|
|
|
|
}
|
|
|
|
x += SmallTextWidth( &string[ i ], 1 );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#include <X11/cursorfont.h>
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void CreateButton( int i, int off_x, int off_y, XFontStruct* f_small,
|
|
|
|
XFontStruct* f_med, XFontStruct* f_big ) {
|
|
|
|
int x, y;
|
|
|
|
XSetWindowAttributes xswa;
|
|
|
|
XFontStruct* finfo;
|
|
|
|
XGCValues val;
|
|
|
|
unsigned long gc_mask;
|
|
|
|
Pixmap pix;
|
|
|
|
XCharStruct xchar;
|
|
|
|
int dir, fa, fd;
|
|
|
|
unsigned long pixel;
|
|
|
|
|
|
|
|
{
|
|
|
|
if ( i < BUTTON_MTH )
|
|
|
|
pixel = COLOR( DISP_PAD );
|
|
|
|
else {
|
|
|
|
if ( opt_gx && buttons[ i ].is_menu )
|
|
|
|
pixel = COLOR( UNDERLAY );
|
|
|
|
else
|
|
|
|
pixel = COLOR( PAD );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* create the buttons subwindows
|
|
|
|
*/
|
|
|
|
buttons[ i ].xwin = XCreateSimpleWindow(
|
|
|
|
dpy, mainW, off_x + buttons[ i ].x, off_y + buttons[ i ].y,
|
|
|
|
buttons[ i ].w, buttons[ i ].h, 0, COLOR( BLACK ), pixel );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XDefineCursor( dpy, buttons[ i ].xwin,
|
|
|
|
XCreateFontCursor( dpy, XC_hand1 ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
xswa.event_mask = LeaveWindowMask | ExposureMask | StructureNotifyMask;
|
|
|
|
xswa.backing_store = Always;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XChangeWindowAttributes( dpy, buttons[ i ].xwin,
|
|
|
|
CWEventMask | CWBackingStore, &xswa );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the released button
|
|
|
|
*/
|
|
|
|
buttons[ i ].map = XCreatePixmap(
|
|
|
|
dpy, buttons[ i ].xwin, buttons[ i ].w, buttons[ i ].h, depth );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, pixel );
|
|
|
|
XFillRectangle( dpy, buttons[ i ].map, gc, 0, 0, buttons[ i ].w,
|
|
|
|
buttons[ i ].h );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( BUTTON ) );
|
|
|
|
XFillRectangle( dpy, buttons[ i ].map, gc, 1, 1, buttons[ i ].w - 2,
|
|
|
|
buttons[ i ].h - 2 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].label != ( char* )0 ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* set font size in gc
|
|
|
|
*/
|
|
|
|
switch ( buttons[ i ].font_size ) {
|
|
|
|
case 0:
|
|
|
|
finfo = f_small;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
finfo = f_big;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
finfo = f_med;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
finfo = f_small;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
val.font = finfo->fid;
|
|
|
|
gc_mask = GCFont;
|
|
|
|
XChangeGC( dpy, gc, gc_mask, &val );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw string centered in button
|
|
|
|
*/
|
|
|
|
XSetBackground( dpy, gc, COLOR( BUTTON ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( buttons[ i ].lc ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XTextExtents( finfo, buttons[ i ].label,
|
|
|
|
( int )strlen( buttons[ i ].label ), &dir, &fa, &fd,
|
|
|
|
&xchar );
|
|
|
|
x = ( buttons[ i ].w - xchar.width ) / 2;
|
|
|
|
y = ( 1 + buttons[ i ].h - ( xchar.ascent + xchar.descent ) ) / 2 +
|
|
|
|
xchar.ascent + 1;
|
|
|
|
XDrawImageString( dpy, buttons[ i ].map, gc, x, y,
|
|
|
|
buttons[ i ].label,
|
|
|
|
( int )strlen( buttons[ i ].label ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, COLOR( BLACK ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
} else if ( buttons[ i ].lw != 0 ) {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* draw pixmap centered in button
|
|
|
|
*/
|
|
|
|
XSetBackground( dpy, gc, COLOR( BUTTON ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( buttons[ i ].lc ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
pix = XCreateBitmapFromData( dpy, buttons[ i ].xwin,
|
|
|
|
( char* )buttons[ i ].lb,
|
|
|
|
buttons[ i ].lw, buttons[ i ].lh );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = ( 1 + buttons[ i ].w - buttons[ i ].lw ) / 2;
|
|
|
|
y = ( 1 + buttons[ i ].h - buttons[ i ].lh ) / 2 + 1;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XCopyPlane( dpy, pix, buttons[ i ].map, gc, 0, 0, buttons[ i ].lw,
|
|
|
|
buttons[ i ].lh, x, y, 1 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFreePixmap( dpy, pix );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, COLOR( BLACK ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* draw edge of button
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( BUT_TOP ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 1, ( int )( buttons[ i ].h - 2 ),
|
|
|
|
1, 1 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 2, ( int )( buttons[ i ].h - 3 ),
|
|
|
|
2, 2 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 3, ( int )( buttons[ i ].h - 4 ),
|
|
|
|
3, 3 );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 1, 1,
|
|
|
|
( int )( buttons[ i ].w - 2 ), 1 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 2, 2,
|
|
|
|
( int )( buttons[ i ].w - 3 ), 2 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 3, 3,
|
|
|
|
( int )( buttons[ i ].w - 4 ), 3 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 4, 4,
|
|
|
|
( int )( buttons[ i ].w - 5 ), 4 );
|
|
|
|
|
|
|
|
XDrawPoint( dpy, buttons[ i ].map, gc, 4, 5 );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( BUT_BOT ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 3, ( int )( buttons[ i ].h - 2 ),
|
|
|
|
( int )( buttons[ i ].w - 2 ),
|
|
|
|
( int )( buttons[ i ].h - 2 ) );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 4, ( int )( buttons[ i ].h - 3 ),
|
|
|
|
( int )( buttons[ i ].w - 3 ),
|
|
|
|
( int )( buttons[ i ].h - 3 ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, ( int )( buttons[ i ].w - 2 ),
|
|
|
|
( int )( buttons[ i ].h - 2 ), ( int )( buttons[ i ].w - 2 ),
|
|
|
|
3 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, ( int )( buttons[ i ].w - 3 ),
|
|
|
|
( int )( buttons[ i ].h - 3 ), ( int )( buttons[ i ].w - 3 ),
|
|
|
|
4 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, ( int )( buttons[ i ].w - 4 ),
|
|
|
|
( int )( buttons[ i ].h - 4 ), ( int )( buttons[ i ].w - 4 ),
|
|
|
|
5 );
|
|
|
|
|
|
|
|
XDrawPoint( dpy, buttons[ i ].map, gc, ( int )( buttons[ i ].w - 5 ),
|
|
|
|
( int )( buttons[ i ].h - 4 ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw frame around button
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( FRAME ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 0, ( int )( buttons[ i ].h - 3 ),
|
|
|
|
0, 2 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 2, 0,
|
|
|
|
( int )( buttons[ i ].w - 3 ), 0 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 2, ( int )( buttons[ i ].h - 1 ),
|
|
|
|
( int )( buttons[ i ].w - 3 ),
|
|
|
|
( int )( buttons[ i ].h - 1 ) );
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, ( int )( buttons[ i ].w - 1 ),
|
|
|
|
( int )( buttons[ i ].h - 3 ), ( int )( buttons[ i ].w - 1 ),
|
|
|
|
2 );
|
|
|
|
|
|
|
|
if ( i == BUTTON_ON ) {
|
|
|
|
XDrawLine( dpy, buttons[ i ].map, gc, 1, 1,
|
|
|
|
( int )( buttons[ i ].w - 2 ), 1 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].map, gc, 1, 2 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].map, gc,
|
|
|
|
( int )( buttons[ i ].w - 2 ), 2 );
|
|
|
|
} else {
|
|
|
|
XDrawPoint( dpy, buttons[ i ].map, gc, 1, 1 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].map, gc,
|
|
|
|
( int )( buttons[ i ].w - 2 ), 1 );
|
|
|
|
}
|
|
|
|
XDrawPoint( dpy, buttons[ i ].map, gc, 1,
|
|
|
|
( int )( buttons[ i ].h - 2 ) );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].map, gc, ( int )( buttons[ i ].w - 2 ),
|
|
|
|
( int )( buttons[ i ].h - 2 ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the depressed button
|
|
|
|
*/
|
|
|
|
buttons[ i ].down = XCreatePixmap(
|
|
|
|
dpy, buttons[ i ].xwin, buttons[ i ].w, buttons[ i ].h, depth );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, pixel );
|
|
|
|
XFillRectangle( dpy, buttons[ i ].down, gc, 0, 0, buttons[ i ].w,
|
|
|
|
buttons[ i ].h );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, COLOR( BUTTON ) );
|
|
|
|
XFillRectangle( dpy, buttons[ i ].down, gc, 1, 1, buttons[ i ].w - 2,
|
|
|
|
buttons[ i ].h - 2 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].label != ( char* )0 ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* set small or big font in gc
|
|
|
|
*/
|
|
|
|
switch ( buttons[ i ].font_size ) {
|
|
|
|
case 0:
|
|
|
|
finfo = f_small;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
finfo = f_big;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
finfo = f_med;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
finfo = f_small;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
val.font = finfo->fid;
|
|
|
|
gc_mask = GCFont;
|
|
|
|
XChangeGC( dpy, gc, gc_mask, &val );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw string centered in button
|
|
|
|
*/
|
|
|
|
XSetBackground( dpy, gc, COLOR( BUTTON ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( buttons[ i ].lc ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XTextExtents( finfo, buttons[ i ].label,
|
|
|
|
( int )strlen( buttons[ i ].label ), &dir, &fa, &fd,
|
|
|
|
&xchar );
|
|
|
|
x = ( buttons[ i ].w - xchar.width ) / 2;
|
|
|
|
y = ( 1 + buttons[ i ].h - ( xchar.ascent + xchar.descent ) ) / 2 +
|
|
|
|
xchar.ascent;
|
|
|
|
XDrawImageString( dpy, buttons[ i ].down, gc, x, y,
|
|
|
|
buttons[ i ].label,
|
|
|
|
( int )strlen( buttons[ i ].label ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, COLOR( BLACK ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw pixmap centered in button
|
|
|
|
*/
|
|
|
|
XSetBackground( dpy, gc, COLOR( BUTTON ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( buttons[ i ].lc ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
pix = XCreateBitmapFromData( dpy, buttons[ i ].xwin,
|
|
|
|
( char* )buttons[ i ].lb,
|
|
|
|
buttons[ i ].lw, buttons[ i ].lh );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = ( 1 + buttons[ i ].w - buttons[ i ].lw ) / 2;
|
|
|
|
y = ( 1 + buttons[ i ].h - buttons[ i ].lh ) / 2;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XCopyPlane( dpy, pix, buttons[ i ].down, gc, 0, 0, buttons[ i ].lw,
|
|
|
|
buttons[ i ].lh, x, y, 1 );
|
|
|
|
|
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
|
|
|
|
XSetBackground( dpy, gc, COLOR( BLACK ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* draw edge of button
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( BUT_TOP ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 2, ( int )( buttons[ i ].h - 4 ),
|
|
|
|
2, 2 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 3, ( int )( buttons[ i ].h - 5 ),
|
|
|
|
3, 3 );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 2, 2,
|
|
|
|
( int )( buttons[ i ].w - 4 ), 2 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 3, 3,
|
|
|
|
( int )( buttons[ i ].w - 5 ), 3 );
|
|
|
|
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, 4, 4 );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( BUT_BOT ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 3, ( int )( buttons[ i ].h - 3 ),
|
|
|
|
( int )( buttons[ i ].w - 3 ),
|
|
|
|
( int )( buttons[ i ].h - 3 ) );
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 4, ( int )( buttons[ i ].h - 4 ),
|
|
|
|
( int )( buttons[ i ].w - 4 ),
|
|
|
|
( int )( buttons[ i ].h - 4 ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, ( int )( buttons[ i ].w - 3 ),
|
|
|
|
( int )( buttons[ i ].h - 3 ), ( int )( buttons[ i ].w - 3 ),
|
|
|
|
3 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, ( int )( buttons[ i ].w - 4 ),
|
|
|
|
( int )( buttons[ i ].h - 4 ), ( int )( buttons[ i ].w - 4 ),
|
|
|
|
4 );
|
|
|
|
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, ( int )( buttons[ i ].w - 5 ),
|
|
|
|
( int )( buttons[ i ].h - 5 ) );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* draw frame around button
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( FRAME ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 0, ( int )( buttons[ i ].h - 3 ),
|
|
|
|
0, 2 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 2, 0,
|
|
|
|
( int )( buttons[ i ].w - 3 ), 0 );
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 2, ( int )( buttons[ i ].h - 1 ),
|
|
|
|
( int )( buttons[ i ].w - 3 ),
|
|
|
|
( int )( buttons[ i ].h - 1 ) );
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, ( int )( buttons[ i ].w - 1 ),
|
|
|
|
( int )( buttons[ i ].h - 3 ), ( int )( buttons[ i ].w - 1 ),
|
|
|
|
2 );
|
|
|
|
|
|
|
|
if ( i == BUTTON_ON ) {
|
|
|
|
XDrawLine( dpy, buttons[ i ].down, gc, 1, 1,
|
|
|
|
( int )( buttons[ i ].w - 2 ), 1 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, 1, 2 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc,
|
|
|
|
( int )( buttons[ i ].w - 2 ), 2 );
|
|
|
|
} else {
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, 1, 1 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc,
|
|
|
|
( int )( buttons[ i ].w - 2 ), 1 );
|
|
|
|
}
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, 1,
|
|
|
|
( int )( buttons[ i ].h - 2 ) );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, ( int )( buttons[ i ].w - 2 ),
|
|
|
|
( int )( buttons[ i ].h - 2 ) );
|
|
|
|
|
|
|
|
if ( i == BUTTON_ON ) {
|
|
|
|
XDrawRectangle( dpy, buttons[ i ].down, gc, 1, 2,
|
|
|
|
buttons[ i ].w - 3, buttons[ i ].h - 4 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, 2, 3 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc,
|
|
|
|
( int )( buttons[ i ].w - 3 ), 3 );
|
|
|
|
} else {
|
|
|
|
XDrawRectangle( dpy, buttons[ i ].down, gc, 1, 1,
|
|
|
|
buttons[ i ].w - 3, buttons[ i ].h - 3 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, 2, 2 );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc,
|
|
|
|
( int )( buttons[ i ].w - 3 ), 2 );
|
|
|
|
}
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, 2,
|
|
|
|
( int )( buttons[ i ].h - 3 ) );
|
|
|
|
XDrawPoint( dpy, buttons[ i ].down, gc, ( int )( buttons[ i ].w - 3 ),
|
|
|
|
( int )( buttons[ i ].h - 3 ) );
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void DrawButtons( void ) {
|
|
|
|
int i;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
|
|
|
if ( buttons[ i ].pressed ) {
|
|
|
|
XCopyArea( dpy, buttons[ i ].down, buttons[ i ].xwin, gc, 0, 0,
|
|
|
|
buttons[ i ].w, buttons[ i ].h, 0, 0 );
|
|
|
|
} else {
|
|
|
|
XCopyArea( dpy, buttons[ i ].map, buttons[ i ].xwin, gc, 0, 0,
|
|
|
|
buttons[ i ].w, buttons[ i ].h, 0, 0 );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
return;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int DrawButton( int i ) {
|
|
|
|
if ( buttons[ i ].pressed ) {
|
|
|
|
XCopyArea( dpy, buttons[ i ].down, buttons[ i ].xwin, gc, 0, 0,
|
|
|
|
buttons[ i ].w, buttons[ i ].h, 0, 0 );
|
|
|
|
} else {
|
|
|
|
XCopyArea( dpy, buttons[ i ].map, buttons[ i ].xwin, gc, 0, 0,
|
|
|
|
buttons[ i ].w, buttons[ i ].h, 0, 0 );
|
|
|
|
}
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void CreateBackground( int width, int height, int w_top, int h_top,
|
|
|
|
keypad_t* keypad ) {
|
|
|
|
XSetBackground( dpy, gc, COLOR( PAD ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFillRectangle( dpy, keypad->pixmap, gc, 0, 0, w_top, h_top );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, COLOR( DISP_PAD ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFillRectangle( dpy, keypad->pixmap, gc, 0, 0, width, height );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void CreateKeypad( unsigned int w, unsigned int h, unsigned int offset_y,
|
|
|
|
unsigned int offset_x, keypad_t* keypad ) {
|
|
|
|
int i, x, y;
|
|
|
|
int wl, wr, ws;
|
|
|
|
Pixmap pix;
|
|
|
|
unsigned long pixel;
|
|
|
|
unsigned int pw, ph;
|
|
|
|
XFontStruct *f_small, *f_med, *f_big;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
f_small = get_font_resource( dpy, "smallLabelFont", "SmallLabelFont" );
|
|
|
|
f_med = get_font_resource( dpy, "mediumLabelFont", "MediumLabelFont" );
|
|
|
|
f_big = get_font_resource( dpy, "largeLabelFont", "LargeLabelFont" );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the character labels
|
|
|
|
*/
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
CreateButton( i, offset_x, offset_y, f_small, f_med, f_big );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( i < BUTTON_MTH )
|
|
|
|
pixel = COLOR( DISP_PAD );
|
|
|
|
else
|
|
|
|
pixel = COLOR( PAD );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].letter != ( char* )0 ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, pixel );
|
|
|
|
XSetForeground( dpy, gc, COLOR( WHITE ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx ) {
|
|
|
|
x = offset_x + buttons[ i ].x + buttons[ i ].w + 3;
|
|
|
|
y = offset_y + buttons[ i ].y + buttons[ i ].h + 1;
|
|
|
|
} else {
|
|
|
|
x = offset_x + buttons[ i ].x + buttons[ i ].w -
|
|
|
|
SmallTextWidth( buttons[ i ].letter, 1 ) / 2 + 5;
|
|
|
|
y = offset_y + buttons[ i ].y + buttons[ i ].h - 2;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
DrawSmallString( dpy, keypad->pixmap, gc, x, y, buttons[ i ].letter,
|
|
|
|
1 );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFreeFont( dpy, f_big );
|
|
|
|
XFreeFont( dpy, f_med );
|
|
|
|
XFreeFont( dpy, f_small );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the bottom labels
|
|
|
|
*/
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].sub != ( char* )0 ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, pixel );
|
|
|
|
XSetForeground( dpy, gc, COLOR( WHITE ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w -
|
|
|
|
SmallTextWidth( buttons[ i ].sub,
|
|
|
|
strlen( buttons[ i ].sub ) ) ) /
|
|
|
|
2;
|
|
|
|
y = offset_y + buttons[ i ].y + buttons[ i ].h + small_ascent + 2;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
DrawSmallString( dpy, keypad->pixmap, gc, x, y, buttons[ i ].sub,
|
|
|
|
strlen( buttons[ i ].sub ) );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the left labels
|
|
|
|
*/
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].left != ( char* )0 ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].is_menu ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the dark shade under the label
|
|
|
|
*/
|
|
|
|
if ( opt_gx ) {
|
|
|
|
pw = 58;
|
|
|
|
ph = 48;
|
|
|
|
} else {
|
|
|
|
pw = 46;
|
|
|
|
ph = 11;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
pix = XCreatePixmap( dpy, keypad->pixmap, pw, ph, depth );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, COLOR( UNDERLAY ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFillRectangle( dpy, pix, gc, 0, 0, pw, ph );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, COLOR( UNDERLAY ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( LEFT ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = ( pw + 1 -
|
|
|
|
SmallTextWidth( buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) ) ) /
|
|
|
|
2;
|
|
|
|
if ( opt_gx )
|
|
|
|
y = 14;
|
|
|
|
else
|
|
|
|
y = 9;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
DrawSmallString( dpy, pix, gc, x, y, buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, pixel );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( !opt_gx ) {
|
|
|
|
XDrawPoint( dpy, pix, gc, 0, 0 );
|
|
|
|
XDrawPoint( dpy, pix, gc, 0, ph - 1 );
|
|
|
|
XDrawPoint( dpy, pix, gc, pw - 1, 0 );
|
|
|
|
XDrawPoint( dpy, pix, gc, pw - 1, ph - 1 );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx ) {
|
|
|
|
x = offset_x + buttons[ i ].x - 6;
|
|
|
|
y = offset_y + buttons[ i ].y - small_ascent -
|
|
|
|
small_descent - 6;
|
|
|
|
} else {
|
|
|
|
x = offset_x + buttons[ i ].x + ( buttons[ i ].w - pw ) / 2;
|
|
|
|
y = offset_y + buttons[ i ].y - small_ascent -
|
|
|
|
small_descent;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XCopyArea( dpy, pix, keypad->pixmap, gc, 0, 0, pw, ph, x, y );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFreePixmap( dpy, pix );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, pixel );
|
|
|
|
XSetForeground( dpy, gc, COLOR( LEFT ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].right == ( char* )0 ) { /* centered label */
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w -
|
|
|
|
SmallTextWidth( buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) ) ) /
|
|
|
|
2;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
} else { /* label to the left */
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
wl = SmallTextWidth( buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) );
|
|
|
|
wr = SmallTextWidth( buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) );
|
|
|
|
ws = SmallTextWidth( " ", 1 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w - ( wl + wr + ws ) ) / 2;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
y = offset_y + buttons[ i ].y - small_descent;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
DrawSmallString( dpy, keypad->pixmap, gc, x, y,
|
|
|
|
buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) );
|
|
|
|
}
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the right labels
|
|
|
|
*/
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( i < BUTTON_MTH )
|
|
|
|
pixel = COLOR( DISP_PAD );
|
|
|
|
else
|
|
|
|
pixel = COLOR( PAD );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].right != ( char* )0 ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].is_menu ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the dark shade under the label
|
|
|
|
*/
|
|
|
|
if ( opt_gx ) {
|
|
|
|
pw = 58;
|
|
|
|
ph = 48;
|
|
|
|
} else {
|
|
|
|
pw = 44;
|
|
|
|
ph = 9;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
pix = XCreatePixmap( dpy, keypad->pixmap, pw, ph, depth );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, COLOR( UNDERLAY ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFillRectangle( dpy, pix, gc, 0, 0, pw, ph );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, COLOR( UNDERLAY ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( RIGHT ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = ( pw + 1 -
|
|
|
|
SmallTextWidth( buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) ) ) /
|
|
|
|
2;
|
|
|
|
if ( opt_gx )
|
|
|
|
y = 14;
|
|
|
|
else
|
|
|
|
y = 8;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
DrawSmallString( dpy, pix, gc, x, y, buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, pixel );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( !opt_gx ) {
|
|
|
|
XDrawPoint( dpy, pix, gc, 0, 0 );
|
|
|
|
XDrawPoint( dpy, pix, gc, 0, ph - 1 );
|
|
|
|
XDrawPoint( dpy, pix, gc, pw - 1, 0 );
|
|
|
|
XDrawPoint( dpy, pix, gc, pw - 1, ph - 1 );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( opt_gx ) {
|
|
|
|
x = offset_x + buttons[ i ].x - 6;
|
|
|
|
y = offset_y + buttons[ i ].y - small_ascent -
|
|
|
|
small_descent - 6;
|
|
|
|
} else {
|
|
|
|
x = offset_x + buttons[ i ].x + ( buttons[ i ].w - pw ) / 2;
|
|
|
|
y = offset_y + buttons[ i ].y - small_ascent -
|
|
|
|
small_descent;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XCopyArea( dpy, pix, keypad->pixmap, gc, 0, 0, pw, ph, x, y );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFreePixmap( dpy, pix );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, pixel );
|
|
|
|
XSetForeground( dpy, gc, COLOR( RIGHT ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( buttons[ i ].left == ( char* )0 ) { /* centered label */
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w -
|
|
|
|
SmallTextWidth( buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) ) ) /
|
|
|
|
2;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
} else { /* label to the right */
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
wl = SmallTextWidth( buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) );
|
|
|
|
wr = SmallTextWidth( buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) );
|
|
|
|
ws = SmallTextWidth( " ", 1 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w - ( wl + wr + ws ) ) / 2 + wl + ws;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
y = offset_y + buttons[ i ].y - small_descent;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
DrawSmallString( dpy, keypad->pixmap, gc, x, y,
|
|
|
|
buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) );
|
|
|
|
}
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* at last draw the v--- LAST ---v thing
|
|
|
|
*/
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( !opt_gx ) {
|
|
|
|
XSetBackground( dpy, gc, COLOR( PAD ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( WHITE ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
pix = XCreateBitmapFromData( dpy, keypad->pixmap, ( char* )last_bits,
|
|
|
|
last_width, last_height );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
x = offset_x + buttons[ BUTTON_1 ].x + buttons[ BUTTON_1 ].w +
|
|
|
|
( buttons[ BUTTON_2 ].x - buttons[ BUTTON_1 ].x -
|
|
|
|
buttons[ BUTTON_1 ].w ) /
|
|
|
|
2;
|
|
|
|
y = offset_y + buttons[ BUTTON_5 ].y + buttons[ BUTTON_5 ].h + 2;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XCopyPlane( dpy, pix, keypad->pixmap, gc, 0, 0, last_width, last_height,
|
|
|
|
x, y, 1 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void CreateBezel( unsigned int width, unsigned int height,
|
|
|
|
unsigned int offset_y, unsigned int offset_x,
|
|
|
|
keypad_t* keypad ) {
|
2023-05-02 14:40:02 +02:00
|
|
|
int i; //, x, y;
|
2023-04-27 13:31:46 +02:00
|
|
|
// Pixmap pix;
|
2023-04-27 12:15:59 +02:00
|
|
|
int display_height = DISPLAY_HEIGHT;
|
|
|
|
int display_width = DISPLAY_WIDTH;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* draw the frame around the display
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD_TOP ) );
|
|
|
|
|
|
|
|
for ( i = 0; i < DISP_FRAME; i++ ) {
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - i ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * i ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + i ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * i ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - i ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * i + 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + i ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * i + 1 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + i ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - i ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + i ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * i ) );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD_BOT ) );
|
|
|
|
|
|
|
|
for ( i = 0; i < DISP_FRAME; i++ ) {
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - i - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - i - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + i - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - i - 1 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - i - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - i - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X - i - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * i - 1 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* round off corners
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_X - DISP_FRAME + 3 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_X - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME + 3 ) );
|
|
|
|
XDrawPoint( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X - DISP_FRAME + 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME + 1 ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 4 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME + 3 ) );
|
|
|
|
XDrawPoint( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 2 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - DISP_FRAME + 1 ) );
|
|
|
|
|
|
|
|
XDrawLine(
|
|
|
|
dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 4 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ) );
|
|
|
|
XDrawLine(
|
|
|
|
dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - DISP_FRAME ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X - DISP_FRAME + 3 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ) );
|
|
|
|
XDrawPoint(
|
|
|
|
dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - DISP_FRAME + 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 2 ) );
|
|
|
|
|
|
|
|
XDrawLine(
|
|
|
|
dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 4 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ) );
|
|
|
|
XDrawLine(
|
|
|
|
dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 4 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1 ) );
|
|
|
|
XDrawPoint(
|
|
|
|
dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width + DISP_FRAME - 2 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 2 ) );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* simulate rounded lcd corners
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( LCD ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + 1 ), ( int )( DISPLAY_OFFSET_X - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height - 2 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X + 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width - 2 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y - 1 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X + 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width - 2 ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + 1 ),
|
|
|
|
( int )( DISPLAY_OFFSET_X + display_width ),
|
|
|
|
( int )( DISPLAY_OFFSET_Y + display_height - 2 ) );
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void DrawMore( unsigned int w, unsigned int h, unsigned int offset_y,
|
|
|
|
unsigned int offset_x, keypad_t* keypad ) {
|
|
|
|
Pixmap pix;
|
2023-04-27 13:31:46 +02:00
|
|
|
int cut = 0;
|
2023-04-27 12:15:59 +02:00
|
|
|
int x, y;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 13:31:46 +02:00
|
|
|
// int display_height = DISPLAY_HEIGHT;
|
2023-04-27 12:15:59 +02:00
|
|
|
int display_width = DISPLAY_WIDTH;
|
|
|
|
/*
|
|
|
|
* lower the whole thing
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD_TOP ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/* bottom lines */
|
|
|
|
int keypad_width = keypad->width;
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 1, ( int )( keypad->height - 1 ),
|
|
|
|
( int )( keypad_width - 1 ), ( int )( keypad->height - 1 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 2, ( int )( keypad->height - 2 ),
|
|
|
|
( int )( keypad_width - 2 ), ( int )( keypad->height - 2 ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/* right lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 1 ),
|
|
|
|
( int )( keypad->height - 1 ), ( int )( keypad->width - 1 ),
|
|
|
|
cut );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 2 ),
|
|
|
|
( int )( keypad->height - 2 ), ( int )( keypad->width - 2 ),
|
|
|
|
cut );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD_TOP ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/* right lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 1 ), cut - 1,
|
|
|
|
( int )( keypad->width - 1 ), 1 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 2 ), cut - 1,
|
|
|
|
( int )( keypad->width - 2 ), 2 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD_BOT ) );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/* top lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 0, 0, ( int )( keypad->width - 2 ), 0 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 1, 1, ( int )( keypad->width - 3 ), 1 );
|
|
|
|
|
|
|
|
/* left lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 0, cut - 1, 0, 0 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 1, cut - 1, 1, 1 );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD_BOT ) );
|
|
|
|
|
|
|
|
/* left lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 0, ( int )( keypad->height - 2 ), 0,
|
|
|
|
cut );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 1, ( int )( keypad->height - 3 ), 1,
|
|
|
|
cut );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* lower the menu buttons
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD_TOP ) );
|
|
|
|
|
|
|
|
/* bottom lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 3, ( int )( keypad->height - 3 ),
|
|
|
|
( int )( keypad->width - 3 ), ( int )( keypad->height - 3 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 4, ( int )( keypad->height - 4 ),
|
|
|
|
( int )( keypad->width - 4 ), ( int )( keypad->height - 4 ) );
|
|
|
|
|
|
|
|
/* right lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 3 ),
|
|
|
|
( int )( keypad->height - 3 ), ( int )( keypad->width - 3 ),
|
|
|
|
cut );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 4 ),
|
|
|
|
( int )( keypad->height - 4 ), ( int )( keypad->width - 4 ),
|
|
|
|
cut );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD_TOP ) );
|
|
|
|
|
|
|
|
/* right lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 3 ), cut - 1,
|
|
|
|
( int )( keypad->width - 3 ), offset_y - 24 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 4 ), cut - 1,
|
|
|
|
( int )( keypad->width - 4 ), offset_y - 23 );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD_BOT ) );
|
|
|
|
|
|
|
|
/* top lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 2, offset_y - 25,
|
|
|
|
( int )( keypad->width - 4 ), offset_y - 25 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 3, offset_y - 24,
|
|
|
|
( int )( keypad->width - 5 ), offset_y - 24 );
|
|
|
|
|
|
|
|
/* left lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 2, cut - 1, 2, offset_y - 24 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 3, cut - 1, 3, offset_y - 23 );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD_BOT ) );
|
|
|
|
|
|
|
|
/* left lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 2, ( int )( keypad->height - 4 ), 2,
|
|
|
|
cut );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 3, ( int )( keypad->height - 5 ), 3,
|
|
|
|
cut );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* lower the keyboard
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD_TOP ) );
|
|
|
|
|
|
|
|
/* bottom lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 5, ( int )( keypad->height - 5 ),
|
|
|
|
( int )( keypad->width - 3 ), ( int )( keypad->height - 5 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 6, ( int )( keypad->height - 6 ),
|
|
|
|
( int )( keypad->width - 4 ), ( int )( keypad->height - 6 ) );
|
|
|
|
|
|
|
|
/* right lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 5 ),
|
|
|
|
( int )( keypad->height - 5 ), ( int )( keypad->width - 5 ),
|
|
|
|
cut + 1 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 6 ),
|
|
|
|
( int )( keypad->height - 6 ), ( int )( keypad->width - 6 ),
|
|
|
|
cut + 2 );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD_BOT ) );
|
|
|
|
|
|
|
|
/* top lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 4, cut, ( int )( keypad->width - 6 ),
|
|
|
|
cut );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 5, cut + 1,
|
|
|
|
( int )( keypad->width - 7 ), cut + 1 );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD_BOT ) );
|
|
|
|
|
|
|
|
/* left lines */
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 4, ( int )( keypad->height - 6 ), 4,
|
|
|
|
cut + 1 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 5, ( int )( keypad->height - 7 ), 5,
|
|
|
|
cut + 2 );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* round off the bottom edge
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD_TOP ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 7 ),
|
|
|
|
( int )( keypad->height - 7 ), ( int )( keypad->width - 7 ),
|
|
|
|
( int )( keypad->height - 14 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 8 ),
|
|
|
|
( int )( keypad->height - 8 ), ( int )( keypad->width - 8 ),
|
|
|
|
( int )( keypad->height - 11 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 7 ),
|
|
|
|
( int )( keypad->height - 7 ), ( int )( keypad->width - 14 ),
|
|
|
|
( int )( keypad->height - 7 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( keypad->width - 7 ),
|
|
|
|
( int )( keypad->height - 8 ), ( int )( keypad->width - 11 ),
|
|
|
|
( int )( keypad->height - 8 ) );
|
|
|
|
XDrawPoint( dpy, keypad->pixmap, gc, ( int )( keypad->width - 9 ),
|
|
|
|
( int )( keypad->height - 9 ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 7, ( int )( keypad->height - 7 ), 13,
|
|
|
|
( int )( keypad->height - 7 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 8, ( int )( keypad->height - 8 ), 10,
|
|
|
|
( int )( keypad->height - 8 ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( PAD_BOT ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 6, ( int )( keypad->height - 8 ), 6,
|
|
|
|
( int )( keypad->height - 14 ) );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, 7, ( int )( keypad->height - 9 ), 7,
|
|
|
|
( int )( keypad->height - 11 ) );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* insert the HP Logo
|
|
|
|
*/
|
|
|
|
|
|
|
|
XSetBackground( dpy, gc, COLOR( LOGO_BACK ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( LOGO ) );
|
|
|
|
|
|
|
|
pix = XCreateBitmapFromData( dpy, keypad->pixmap, ( char* )hp_bits,
|
|
|
|
hp_width, hp_height );
|
|
|
|
|
|
|
|
if ( opt_gx )
|
|
|
|
x = DISPLAY_OFFSET_X - 6;
|
|
|
|
else
|
|
|
|
x = DISPLAY_OFFSET_X;
|
|
|
|
|
|
|
|
XCopyPlane( dpy, pix, keypad->pixmap, gc, 0, 0, hp_width, hp_height, x, 10,
|
|
|
|
1 );
|
|
|
|
|
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
|
|
|
|
if ( !opt_gx ) {
|
|
|
|
XSetForeground( dpy, gc, COLOR( FRAME ) );
|
|
|
|
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )DISPLAY_OFFSET_X, 9,
|
|
|
|
( int )( DISPLAY_OFFSET_X + hp_width - 1 ), 9 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )( DISPLAY_OFFSET_X - 1 ), 10,
|
|
|
|
( int )( DISPLAY_OFFSET_X - 1 ), 10 + hp_height - 1 );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc, ( int )DISPLAY_OFFSET_X,
|
|
|
|
10 + hp_height, ( int )( DISPLAY_OFFSET_X + hp_width - 1 ),
|
|
|
|
10 + hp_height );
|
|
|
|
XDrawLine( dpy, keypad->pixmap, gc,
|
|
|
|
( int )( DISPLAY_OFFSET_X + hp_width ), 10,
|
|
|
|
( int )( DISPLAY_OFFSET_X + hp_width ), 10 + hp_height - 1 );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* write the name of it
|
2022-03-24 13:41:22 +01:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetBackground( dpy, gc, COLOR( DISP_PAD ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( LABEL ) );
|
|
|
|
|
|
|
|
if ( opt_gx ) {
|
|
|
|
x = DISPLAY_OFFSET_X + display_width - gx_128K_ram_width +
|
|
|
|
gx_128K_ram_x_hot + 2;
|
|
|
|
y = 10 + gx_128K_ram_y_hot;
|
|
|
|
pix = XCreateBitmapFromData( dpy, keypad->pixmap,
|
|
|
|
( char* )gx_128K_ram_bits,
|
|
|
|
gx_128K_ram_width, gx_128K_ram_height );
|
|
|
|
XCopyPlane( dpy, pix, keypad->pixmap, gc, 0, 0, gx_128K_ram_width,
|
|
|
|
gx_128K_ram_height, x, y, 1 );
|
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( LOGO ) );
|
|
|
|
x = DISPLAY_OFFSET_X + hp_width;
|
|
|
|
y = hp_height + 8 - hp48gx_height;
|
|
|
|
pix = XCreateBitmapFromData( dpy, keypad->pixmap, ( char* )hp48gx_bits,
|
|
|
|
hp48gx_width, hp48gx_height );
|
|
|
|
XCopyPlane( dpy, pix, keypad->pixmap, gc, 0, 0, hp48gx_width,
|
|
|
|
hp48gx_height, x, y, 1 );
|
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
|
|
|
|
XSetFillStyle( dpy, gc, FillStippled );
|
|
|
|
x = DISPLAY_OFFSET_X + DISPLAY_WIDTH - gx_128K_ram_width +
|
|
|
|
gx_silver_x_hot + 2;
|
|
|
|
y = 10 + gx_silver_y_hot;
|
|
|
|
pix =
|
|
|
|
XCreateBitmapFromData( dpy, keypad->pixmap, ( char* )gx_silver_bits,
|
|
|
|
gx_silver_width, gx_silver_height );
|
|
|
|
XSetStipple( dpy, gc, pix );
|
|
|
|
XSetTSOrigin( dpy, gc, x, y );
|
|
|
|
XFillRectangle( dpy, keypad->pixmap, gc, x, y, gx_silver_width,
|
|
|
|
gx_silver_height );
|
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
|
|
|
|
XSetForeground( dpy, gc, COLOR( RIGHT ) );
|
|
|
|
x = DISPLAY_OFFSET_X + display_width - gx_128K_ram_width +
|
|
|
|
gx_green_x_hot + 2;
|
|
|
|
y = 10 + gx_green_y_hot;
|
|
|
|
pix =
|
|
|
|
XCreateBitmapFromData( dpy, keypad->pixmap, ( char* )gx_green_bits,
|
|
|
|
gx_green_width, gx_green_height );
|
|
|
|
XSetStipple( dpy, gc, pix );
|
|
|
|
XSetTSOrigin( dpy, gc, x, y );
|
|
|
|
XFillRectangle( dpy, keypad->pixmap, gc, x, y, gx_green_width,
|
|
|
|
gx_green_height );
|
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
|
|
|
|
XSetTSOrigin( dpy, gc, 0, 0 );
|
|
|
|
XSetFillStyle( dpy, gc, FillSolid );
|
|
|
|
} else {
|
|
|
|
x = DISPLAY_OFFSET_X;
|
|
|
|
y = TOP_SKIP - DISP_FRAME - hp48sx_height - 3;
|
|
|
|
|
|
|
|
pix = XCreateBitmapFromData( dpy, keypad->pixmap, ( char* )hp48sx_bits,
|
|
|
|
hp48sx_width, hp48sx_height );
|
|
|
|
|
|
|
|
XCopyPlane( dpy, pix, keypad->pixmap, gc, 0, 0, hp48sx_width,
|
|
|
|
hp48sx_height, x, y, 1 );
|
|
|
|
|
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
|
|
|
|
x = DISPLAY_OFFSET_X + display_width - 1 - science_width;
|
|
|
|
y = TOP_SKIP - DISP_FRAME - science_height - 4;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
pix = XCreateBitmapFromData( dpy, keypad->pixmap, ( char* )science_bits,
|
|
|
|
science_width, science_height );
|
|
|
|
|
|
|
|
XCopyPlane( dpy, pix, keypad->pixmap, gc, 0, 0, science_width,
|
|
|
|
science_height, x, y, 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* that's it. Ooph.
|
|
|
|
*/
|
|
|
|
return;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void DrawKeypad( keypad_t* keypad ) {
|
|
|
|
XCopyArea( dpy, keypad->pixmap, mainW, gc, 0, 0, keypad->width,
|
|
|
|
keypad->height, 0, 0 );
|
2015-07-26 11:16:05 +02:00
|
|
|
return;
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void CreateIcon( void ) {
|
|
|
|
XSetWindowAttributes xswa;
|
|
|
|
XWindowAttributes xwa;
|
|
|
|
Pixmap tmp_pix;
|
|
|
|
int p;
|
|
|
|
|
|
|
|
XGetWindowAttributes( dpy, iconW, &xwa );
|
|
|
|
xswa.event_mask = xwa.your_event_mask | ExposureMask;
|
|
|
|
xswa.backing_store = Always;
|
|
|
|
XChangeWindowAttributes( dpy, iconW, CWEventMask | CWBackingStore, &xswa );
|
|
|
|
|
|
|
|
icon_pix =
|
|
|
|
XCreatePixmap( dpy, iconW, hp48_icon_width, hp48_icon_height, depth );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* draw the icon pixmap
|
|
|
|
*/
|
|
|
|
if ( icon_color_mode == COLOR_MODE_MONO ) {
|
|
|
|
tmp_pix = XCreateBitmapFromData(
|
|
|
|
dpy, iconW, ( char* )icon_maps[ ICON_MAP ].bits,
|
|
|
|
icon_maps[ ICON_MAP ].w, icon_maps[ ICON_MAP ].h );
|
|
|
|
XSetForeground( dpy, gc, COLOR( BLACK ) );
|
|
|
|
XSetBackground( dpy, gc, COLOR( WHITE ) );
|
|
|
|
XCopyPlane( dpy, tmp_pix, icon_pix, gc, 0, 0, icon_maps[ ICON_MAP ].w,
|
|
|
|
icon_maps[ ICON_MAP ].h, 0, 0, 1 );
|
|
|
|
XFreePixmap( dpy, tmp_pix );
|
|
|
|
} else {
|
|
|
|
XSetFillStyle( dpy, gc, FillStippled );
|
|
|
|
for ( p = FIRST_MAP; p <= LAST_MAP; p++ ) {
|
|
|
|
tmp_pix =
|
|
|
|
XCreateBitmapFromData( dpy, iconW, ( char* )icon_maps[ p ].bits,
|
|
|
|
icon_maps[ p ].w, icon_maps[ p ].h );
|
|
|
|
XSetStipple( dpy, gc, tmp_pix );
|
|
|
|
XSetForeground( dpy, gc, COLOR( icon_maps[ p ].c ) );
|
|
|
|
XFillRectangle( dpy, icon_pix, gc, 0, 0, icon_maps[ p ].w,
|
|
|
|
icon_maps[ p ].h );
|
|
|
|
XFreePixmap( dpy, tmp_pix );
|
|
|
|
}
|
|
|
|
XSetFillStyle( dpy, gc, FillSolid );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* draw frame around icon
|
|
|
|
*/
|
|
|
|
XSetForeground( dpy, gc, COLOR( BLACK ) );
|
|
|
|
XDrawRectangle( dpy, icon_pix, gc, 0, 0, icon_maps[ ICON_MAP ].w - 1,
|
|
|
|
icon_maps[ ICON_MAP ].h - 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* draw the display
|
2022-03-24 13:41:22 +01:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetFillStyle( dpy, gc, FillStippled );
|
|
|
|
icon_disp_pix = XCreateBitmapFromData(
|
|
|
|
dpy, iconW, ( char* )icon_maps[ DISP_MAP ].bits,
|
|
|
|
icon_maps[ DISP_MAP ].w, icon_maps[ DISP_MAP ].h );
|
|
|
|
XSetStipple( dpy, gc, icon_disp_pix );
|
|
|
|
if ( icon_color_mode == COLOR_MODE_MONO )
|
|
|
|
XSetForeground( dpy, gc, COLOR( WHITE ) );
|
2022-03-24 13:41:22 +01:00
|
|
|
else
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, COLOR( icon_maps[ DISP_MAP ].c ) );
|
|
|
|
XFillRectangle( dpy, icon_pix, gc, 0, 0, icon_maps[ DISP_MAP ].w,
|
|
|
|
icon_maps[ DISP_MAP ].h );
|
|
|
|
|
2022-03-24 13:41:22 +01:00
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* draw the 'x48' string
|
2022-03-24 13:41:22 +01:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
icon_text_pix =
|
|
|
|
XCreateBitmapFromData( dpy, iconW, ( char* )icon_maps[ ON_MAP ].bits,
|
|
|
|
icon_maps[ ON_MAP ].w, icon_maps[ ON_MAP ].h );
|
|
|
|
XSetStipple( dpy, gc, icon_text_pix );
|
|
|
|
if ( icon_color_mode == COLOR_MODE_MONO )
|
|
|
|
XSetForeground( dpy, gc, COLOR( BLACK ) );
|
2022-03-24 13:41:22 +01:00
|
|
|
else
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetForeground( dpy, gc, COLOR( icon_maps[ ON_MAP ].c ) );
|
|
|
|
XFillRectangle( dpy, icon_pix, gc, 0, 0, icon_maps[ ON_MAP ].w,
|
|
|
|
icon_maps[ ON_MAP ].h );
|
|
|
|
XSetFillStyle( dpy, gc, FillSolid );
|
|
|
|
|
|
|
|
return;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void refresh_icon( void ) {
|
|
|
|
int icon_state;
|
|
|
|
|
|
|
|
icon_state =
|
|
|
|
( ( display.on && !( ( ANN_IO & display.annunc ) == ANN_IO ) ) ||
|
|
|
|
( display.on && !( ( ANN_ALPHA & display.annunc ) == ANN_ALPHA ) ) );
|
|
|
|
if ( icon_state == last_icon_state )
|
|
|
|
return;
|
|
|
|
|
|
|
|
last_icon_state = icon_state;
|
|
|
|
XSetFillStyle( dpy, gc, FillStippled );
|
|
|
|
if ( icon_state ) {
|
|
|
|
/*
|
|
|
|
* draw the 'x48' string
|
|
|
|
*/
|
|
|
|
XSetStipple( dpy, gc, icon_text_pix );
|
|
|
|
if ( icon_color_mode == COLOR_MODE_MONO )
|
|
|
|
XSetForeground( dpy, gc, COLOR( BLACK ) );
|
|
|
|
else
|
|
|
|
XSetForeground( dpy, gc, COLOR( icon_maps[ ON_MAP ].c ) );
|
|
|
|
XFillRectangle( dpy, icon_pix, gc, 0, 0, icon_maps[ ON_MAP ].w,
|
|
|
|
icon_maps[ ON_MAP ].h );
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* clear the display
|
|
|
|
*/
|
|
|
|
XSetFillStyle( dpy, gc, FillStippled );
|
|
|
|
XSetStipple( dpy, gc, icon_disp_pix );
|
|
|
|
if ( icon_color_mode == COLOR_MODE_MONO )
|
|
|
|
XSetForeground( dpy, gc, COLOR( WHITE ) );
|
|
|
|
else
|
|
|
|
XSetForeground( dpy, gc, COLOR( icon_maps[ DISP_MAP ].c ) );
|
|
|
|
XFillRectangle( dpy, icon_pix, gc, 0, 0, icon_maps[ DISP_MAP ].w,
|
|
|
|
icon_maps[ DISP_MAP ].h );
|
|
|
|
}
|
|
|
|
XSetFillStyle( dpy, gc, FillSolid );
|
|
|
|
if ( iconW ) {
|
|
|
|
XCopyArea( dpy, icon_pix, iconW, gc, 0, 0, hp48_icon_width,
|
|
|
|
hp48_icon_height, 0, 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DrawIcon( void ) {
|
|
|
|
XCopyArea( dpy, icon_pix, iconW, gc, 0, 0, hp48_icon_width,
|
|
|
|
hp48_icon_height, 0, 0 );
|
|
|
|
return;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
int handle_xerror( Display* the_dpy, XErrorEvent* eev ) {
|
|
|
|
xerror_flag = 1;
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void CreateDispWindow( void ) {
|
|
|
|
XSetWindowAttributes xswa;
|
|
|
|
XGCValues val;
|
|
|
|
unsigned long gc_mask;
|
|
|
|
static XRectangle rect;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* create the display subwindow
|
|
|
|
*/
|
|
|
|
disp.w = DISPLAY_WIDTH;
|
|
|
|
disp.h = DISPLAY_HEIGHT;
|
|
|
|
|
|
|
|
disp.win = XCreateSimpleWindow( dpy, mainW, ( int )DISPLAY_OFFSET_X,
|
|
|
|
( int )DISPLAY_OFFSET_Y, disp.w, disp.h, 0,
|
|
|
|
COLOR( BLACK ), COLOR( LCD ) );
|
|
|
|
|
|
|
|
disp.mapped = 1;
|
|
|
|
|
|
|
|
xswa.event_mask = ExposureMask | StructureNotifyMask;
|
|
|
|
xswa.backing_store = Always;
|
|
|
|
|
|
|
|
XChangeWindowAttributes( dpy, disp.win, CWEventMask | CWBackingStore,
|
|
|
|
&xswa );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* set up the gc
|
|
|
|
*/
|
|
|
|
val.foreground = COLOR( LCD );
|
|
|
|
val.background = COLOR( LCD );
|
|
|
|
val.function = GXcopy;
|
|
|
|
gc_mask = GCForeground | GCBackground | GCFunction;
|
|
|
|
disp.gc = XCreateGC( dpy, mainW, gc_mask, &val );
|
|
|
|
|
|
|
|
XSetForeground( dpy, disp.gc, COLOR( PIXEL ) );
|
|
|
|
|
|
|
|
#ifdef HAVE_XSHM
|
|
|
|
|
|
|
|
disp.display_update = UPDATE_DISP | UPDATE_MENU;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
xerror_flag = 0;
|
|
|
|
XSetErrorHandler( handle_xerror );
|
|
|
|
XFlush( dpy );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
disp.disp_image = NULL;
|
|
|
|
disp.menu_image = NULL;
|
|
|
|
if ( shm_flag ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* create XShmImage for DISP
|
|
|
|
*/
|
|
|
|
disp.disp_image = XShmCreateImage( dpy, None, 1, XYBitmap, NULL,
|
|
|
|
&disp.disp_info, 262, 128 );
|
|
|
|
if ( disp.disp_image == NULL ) {
|
|
|
|
shm_flag = 0;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr,
|
|
|
|
"%s: XShm error in CreateImage(DISP), disabling.\n",
|
|
|
|
progname );
|
|
|
|
goto shm_error;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* get ID of shared memory block for DISP
|
|
|
|
*/
|
|
|
|
disp.disp_info.shmid = shmget(
|
|
|
|
IPC_PRIVATE,
|
|
|
|
( disp.disp_image->bytes_per_line * disp.disp_image->height ),
|
|
|
|
IPC_CREAT | 0777 );
|
|
|
|
if ( disp.disp_info.shmid < 0 ) {
|
|
|
|
XDestroyImage( disp.disp_image );
|
|
|
|
disp.disp_image = NULL;
|
|
|
|
shm_flag = 0;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: XShm error in shmget(DISP), disabling.\n",
|
|
|
|
progname );
|
|
|
|
goto shm_error;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* get address of shared memory block for DISP
|
|
|
|
*/
|
|
|
|
disp.disp_info.shmaddr = ( char* )shmat( disp.disp_info.shmid, 0, 0 );
|
|
|
|
if ( disp.disp_info.shmaddr == ( ( char* )-1 ) ) {
|
|
|
|
XDestroyImage( disp.disp_image );
|
|
|
|
disp.disp_image = NULL;
|
|
|
|
shm_flag = 0;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: XShm error in shmat(DISP), disabling.\n",
|
|
|
|
progname );
|
|
|
|
goto shm_error;
|
|
|
|
}
|
|
|
|
disp.disp_image->data = disp.disp_info.shmaddr;
|
|
|
|
disp.disp_info.readOnly = False;
|
|
|
|
XShmAttach( dpy, &disp.disp_info );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* create XShmImage for MENU
|
|
|
|
*/
|
|
|
|
disp.menu_image = XShmCreateImage( dpy, None, 1, XYBitmap, NULL,
|
|
|
|
&disp.menu_info, 262, 128 );
|
|
|
|
if ( disp.menu_image == NULL ) {
|
|
|
|
XDestroyImage( disp.disp_image );
|
|
|
|
disp.disp_image = NULL;
|
|
|
|
shm_flag = 0;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr,
|
|
|
|
"%s: XShm error in CreateImage(MENU), disabling.\n",
|
|
|
|
progname );
|
|
|
|
goto shm_error;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* get ID of shared memory block for MENU
|
|
|
|
*/
|
|
|
|
disp.menu_info.shmid = shmget(
|
|
|
|
IPC_PRIVATE,
|
|
|
|
( disp.menu_image->bytes_per_line * disp.menu_image->height ),
|
|
|
|
IPC_CREAT | 0777 );
|
|
|
|
if ( disp.menu_info.shmid < 0 ) {
|
|
|
|
XDestroyImage( disp.disp_image );
|
|
|
|
disp.disp_image = NULL;
|
|
|
|
XDestroyImage( disp.menu_image );
|
|
|
|
disp.menu_image = NULL;
|
|
|
|
shm_flag = 0;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: XShm error in shmget(MENU), disabling.\n",
|
|
|
|
progname );
|
|
|
|
goto shm_error;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* get address of shared memory block for MENU
|
|
|
|
*/
|
|
|
|
disp.menu_info.shmaddr = ( char* )shmat( disp.menu_info.shmid, 0, 0 );
|
|
|
|
if ( disp.menu_info.shmaddr == ( ( char* )-1 ) ) {
|
|
|
|
XDestroyImage( disp.disp_image );
|
|
|
|
disp.disp_image = NULL;
|
|
|
|
XDestroyImage( disp.menu_image );
|
|
|
|
disp.menu_image = NULL;
|
|
|
|
shm_flag = 0;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: XShm error in shmat(MENU), disabling.\n",
|
|
|
|
progname );
|
|
|
|
goto shm_error;
|
|
|
|
}
|
|
|
|
disp.menu_image->data = disp.menu_info.shmaddr;
|
|
|
|
disp.menu_info.readOnly = False;
|
|
|
|
XShmAttach( dpy, &disp.menu_info );
|
|
|
|
|
|
|
|
XFlush( dpy );
|
|
|
|
XSync( dpy, 0 );
|
|
|
|
sleep( 1 );
|
|
|
|
|
|
|
|
if ( xerror_flag ) {
|
|
|
|
XDestroyImage( disp.disp_image );
|
|
|
|
disp.disp_image = NULL;
|
|
|
|
XDestroyImage( disp.menu_image );
|
|
|
|
disp.menu_image = NULL;
|
|
|
|
shm_flag = 0;
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr, "%s: XShm error in shmget(MENU), disabling.\n",
|
|
|
|
progname );
|
|
|
|
goto shm_error;
|
|
|
|
} else {
|
|
|
|
shmctl( disp.disp_info.shmid, IPC_RMID, 0 );
|
|
|
|
shmctl( disp.menu_info.shmid, IPC_RMID, 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
memset( disp.disp_image->data, 0,
|
|
|
|
( size_t )( disp.disp_image->bytes_per_line *
|
|
|
|
disp.disp_image->height ) );
|
|
|
|
memset( disp.menu_image->data, 0,
|
|
|
|
( size_t )( disp.menu_image->bytes_per_line *
|
|
|
|
disp.menu_image->height ) );
|
|
|
|
|
|
|
|
if ( verbose )
|
|
|
|
printf( "%s: using XShm extension.\n", progname );
|
|
|
|
|
|
|
|
CompletionType = XShmGetEventBase( dpy ) + ShmCompletion;
|
|
|
|
}
|
|
|
|
shm_error:
|
|
|
|
|
|
|
|
XSetErrorHandler( NULL );
|
|
|
|
XFlush( dpy );
|
|
|
|
|
|
|
|
if ( !shm_flag ) {
|
|
|
|
#endif
|
|
|
|
rect.x = 5;
|
|
|
|
rect.y = 0;
|
|
|
|
rect.width = 262;
|
|
|
|
rect.height = disp.h;
|
|
|
|
XSetClipRectangles( dpy, disp.gc, 0, 0, &rect, 1, Unsorted );
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CreateWindows( int argc, char** argv ) {
|
|
|
|
XSizeHints hint, ih;
|
|
|
|
XWMHints wmh;
|
|
|
|
XClassHint clh;
|
|
|
|
unsigned int class;
|
|
|
|
XGCValues val;
|
|
|
|
unsigned long gc_mask;
|
|
|
|
unsigned int mask;
|
|
|
|
XSetWindowAttributes xswa;
|
|
|
|
XTextProperty wname, iname;
|
|
|
|
Atom protocols[ 2 ];
|
|
|
|
char *name, *user_geom, def_geom[ 40 ];
|
|
|
|
int info, x, y, w, h;
|
|
|
|
unsigned int width, height;
|
|
|
|
|
|
|
|
if ( opt_gx ) {
|
|
|
|
buttons = buttons_gx;
|
|
|
|
colors = colors_gx;
|
|
|
|
icon_maps = icon_maps_gx;
|
|
|
|
} else {
|
|
|
|
buttons = buttons_sx;
|
|
|
|
colors = colors_sx;
|
|
|
|
icon_maps = icon_maps_sx;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( netbook ) {
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < 6; i++ ) {
|
|
|
|
buttons[ i ].x -= 3;
|
|
|
|
buttons[ i ].y += 300;
|
|
|
|
}
|
|
|
|
for ( ; i <= LAST_BUTTON; i++ ) {
|
|
|
|
buttons[ i ].x += 317;
|
|
|
|
buttons[ i ].y -= 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class = InputOutput;
|
|
|
|
visual = get_visual_resource( dpy, "visual", "Visual", &depth );
|
|
|
|
if ( visual != DefaultVisual( dpy, screen ) ) {
|
|
|
|
if ( visual->class == DirectColor )
|
|
|
|
cmap = XCreateColormap( dpy, RootWindow( dpy, screen ), visual,
|
|
|
|
AllocAll );
|
|
|
|
else
|
|
|
|
cmap = XCreateColormap( dpy, RootWindow( dpy, screen ), visual,
|
|
|
|
AllocNone );
|
|
|
|
} else
|
|
|
|
cmap = DefaultColormap( dpy, screen );
|
|
|
|
|
|
|
|
direct_color = 0;
|
|
|
|
switch ( visual->class ) {
|
|
|
|
case DirectColor:
|
|
|
|
direct_color = 1;
|
|
|
|
case GrayScale:
|
|
|
|
case PseudoColor:
|
|
|
|
dynamic_color = 1;
|
|
|
|
break;
|
|
|
|
case StaticGray:
|
|
|
|
case StaticColor:
|
|
|
|
case TrueColor:
|
|
|
|
default:
|
|
|
|
dynamic_color = 0;
|
|
|
|
break;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( ( visual->class == StaticGray ) || ( visual->class == GrayScale ) )
|
|
|
|
color_mode = COLOR_MODE_GRAY;
|
|
|
|
else
|
|
|
|
color_mode = COLOR_MODE_COLOR;
|
|
|
|
if ( get_boolean_resource( "gray", "Gray" ) )
|
|
|
|
color_mode = COLOR_MODE_GRAY;
|
|
|
|
|
|
|
|
if ( get_boolean_resource( "mono", "Mono" ) )
|
|
|
|
color_mode = COLOR_MODE_MONO;
|
|
|
|
if ( depth == 1 )
|
|
|
|
color_mode = COLOR_MODE_MONO;
|
|
|
|
|
|
|
|
icon_color_mode = color_mode;
|
|
|
|
if ( get_boolean_resource( "monoIcon", "Mono" ) )
|
|
|
|
icon_color_mode = COLOR_MODE_MONO;
|
|
|
|
|
|
|
|
clh.res_name = res_name;
|
|
|
|
clh.res_class = res_class;
|
|
|
|
if ( !XStringListToTextProperty( &progname, 1, &iname ) )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ( ( name = get_string_resource( "title", "Title" ) ) == ( char* )0 ) {
|
|
|
|
name = ( char* )malloc( 128 );
|
|
|
|
if ( name == ( char* )0 ) {
|
|
|
|
sprintf( errbuf, "malloc failed.\n" );
|
|
|
|
fatal_exit();
|
|
|
|
}
|
|
|
|
sprintf( name, "%s-%d.%d.%d", progname, saturn.version[ 0 ],
|
|
|
|
saturn.version[ 1 ], saturn.version[ 2 ] );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( !XStringListToTextProperty( &name, 1, &wname ) )
|
|
|
|
return -1;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* Set some Window Attributes
|
|
|
|
*/
|
|
|
|
xswa.colormap = cmap;
|
|
|
|
mask = CWColormap;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* create the window
|
2015-07-26 11:16:05 +02:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
width = KEYBOARD_WIDTH + 2 * SIDE_SKIP;
|
|
|
|
if ( netbook ) {
|
|
|
|
height = KEYBOARD_HEIGHT;
|
|
|
|
} else {
|
|
|
|
height = DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + DISP_KBD_SKIP +
|
|
|
|
KEYBOARD_HEIGHT + BOTTOM_SKIP;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
mainW = XCreateWindow( dpy, RootWindow( dpy, screen ), 0, 0, width, height,
|
|
|
|
0, ( int )depth, class, visual, mask, &xswa );
|
|
|
|
|
|
|
|
if ( mainW == 0 )
|
|
|
|
return -1;
|
|
|
|
|
2015-07-26 11:16:05 +02:00
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* allocate my colors
|
2015-07-26 11:16:05 +02:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
AllocColors();
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* parse -geometry ...
|
2015-07-26 11:16:05 +02:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
hint.x = hint.y = 0;
|
|
|
|
hint.min_width = hint.max_width = hint.base_width = hint.width = width;
|
|
|
|
hint.min_height = hint.max_height = hint.base_height = hint.height = height;
|
|
|
|
hint.win_gravity = NorthWestGravity;
|
|
|
|
hint.flags = PSize | PMinSize | PMaxSize | PBaseSize | PWinGravity;
|
|
|
|
|
|
|
|
sprintf( def_geom, "%ux%u", width, height );
|
|
|
|
user_geom = get_string_resource( "geometry", "Geometry" );
|
|
|
|
|
|
|
|
info = XWMGeometry( dpy, screen, user_geom, def_geom, 0, &hint, &x, &y, &w,
|
|
|
|
&h, &hint.win_gravity );
|
|
|
|
|
|
|
|
if ( info & ( XValue | YValue ) ) {
|
|
|
|
if ( info & XValue )
|
|
|
|
hint.x = x;
|
|
|
|
if ( info & YValue )
|
|
|
|
hint.y = y;
|
|
|
|
hint.flags |= USPosition;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* check if we start iconic
|
2015-07-26 11:16:05 +02:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( get_boolean_resource( "iconic", "Iconic" ) )
|
|
|
|
wmh.initial_state = IconicState;
|
|
|
|
else
|
|
|
|
wmh.initial_state = NormalState;
|
|
|
|
wmh.input = True;
|
|
|
|
wmh.flags = StateHint | InputHint;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* Set some more Window Attributes
|
2015-07-26 11:16:05 +02:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
xswa.background_pixel = COLOR( PAD );
|
|
|
|
xswa.border_pixel = COLOR( BLACK );
|
|
|
|
xswa.backing_store = Always;
|
|
|
|
xswa.win_gravity = hint.win_gravity;
|
|
|
|
xswa.bit_gravity = NorthWestGravity;
|
|
|
|
xswa.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
|
|
|
|
ButtonReleaseMask | ExposureMask | KeymapStateMask |
|
|
|
|
EnterWindowMask | StructureNotifyMask | FocusChangeMask;
|
|
|
|
mask = CWBackPixel | CWBorderPixel | CWBackingStore | CWEventMask |
|
|
|
|
CWBitGravity | CWWinGravity;
|
|
|
|
XChangeWindowAttributes( dpy, mainW, mask, &xswa );
|
|
|
|
XMoveWindow( dpy, mainW, hint.x, hint.y );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
/*
|
2023-04-27 12:15:59 +02:00
|
|
|
* create the icon
|
2015-07-26 11:16:05 +02:00
|
|
|
*/
|
2023-04-27 12:15:59 +02:00
|
|
|
xswa.colormap = cmap;
|
|
|
|
mask = CWColormap;
|
|
|
|
iconW = XCreateWindow( dpy, RootWindow( dpy, screen ), 0, 0,
|
|
|
|
hp48_icon_width, hp48_icon_height, 0, ( int )depth,
|
|
|
|
class, visual, mask, &xswa );
|
|
|
|
|
|
|
|
if ( iconW == 0 )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
wmh.icon_window = iconW;
|
|
|
|
wmh.window_group = mainW;
|
|
|
|
wmh.flags |= ( IconWindowHint | WindowGroupHint );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* set icon position if requested
|
|
|
|
*/
|
|
|
|
ih.x = ih.y = 0;
|
|
|
|
ih.min_width = ih.max_width = ih.base_width = ih.width = hp48_icon_width;
|
|
|
|
ih.min_height = ih.max_height = ih.base_height = ih.height =
|
|
|
|
hp48_icon_height;
|
|
|
|
ih.win_gravity = NorthWestGravity;
|
|
|
|
ih.flags = PSize | PMinSize | PMaxSize | PBaseSize | PWinGravity;
|
|
|
|
|
|
|
|
user_geom = get_string_resource( "iconGeom", "IconGeom" );
|
|
|
|
info = XWMGeometry( dpy, screen, user_geom, ( char* )0, 0, &ih, &x, &y, &w,
|
|
|
|
&h, &ih.win_gravity );
|
|
|
|
|
|
|
|
if ( ( info & XValue ) && ( info & YValue ) ) {
|
|
|
|
wmh.icon_x = x;
|
|
|
|
wmh.icon_y = y;
|
|
|
|
wmh.flags |= IconPositionHint;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* set some more attributes of icon window
|
|
|
|
*/
|
|
|
|
xswa.background_pixel = COLOR( BLACK );
|
|
|
|
xswa.border_pixel = COLOR( BLACK );
|
|
|
|
xswa.backing_store = NotUseful;
|
|
|
|
xswa.win_gravity = ih.win_gravity;
|
|
|
|
xswa.bit_gravity = NorthWestGravity;
|
|
|
|
mask = CWBackPixel | CWBorderPixel | CWBackingStore | CWBitGravity |
|
|
|
|
CWWinGravity;
|
|
|
|
XChangeWindowAttributes( dpy, iconW, mask, &xswa );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* tell window manager all the stuff we dug out
|
|
|
|
*/
|
|
|
|
XSetWMProperties( dpy, mainW, &wname, &iname, argv, argc, &hint, &wmh,
|
|
|
|
&clh );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* turn on WM_DELETE_WINDOW
|
|
|
|
*/
|
|
|
|
wm_delete_window = XInternAtom( dpy, "WM_DELETE_WINDOW", 0 );
|
|
|
|
wm_save_yourself = XInternAtom( dpy, "WM_SAVE_YOURSELF", 0 );
|
|
|
|
wm_protocols = XInternAtom( dpy, "WM_PROTOCOLS", 0 );
|
|
|
|
protocols[ 0 ] = wm_delete_window;
|
|
|
|
protocols[ 1 ] = wm_save_yourself;
|
|
|
|
XSetWMProtocols( dpy, mainW, protocols, 2 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* turn off icon name for olwm, olvwm
|
|
|
|
*/
|
|
|
|
ol_decor_icon_name = XInternAtom( dpy, "_OL_DECOR_ICON_NAME", 0 );
|
|
|
|
ol_decor_del = XInternAtom( dpy, "_OL_DECOR_DEL", 0 );
|
|
|
|
atom_type = XInternAtom( dpy, "ATOM", 0 );
|
|
|
|
XChangeProperty( dpy, mainW, ol_decor_del, atom_type, 32, PropModeReplace,
|
|
|
|
( unsigned char* )&ol_decor_icon_name, 1 );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* set up the GC's
|
|
|
|
*/
|
|
|
|
val.foreground = COLOR( WHITE );
|
|
|
|
val.background = COLOR( BLACK );
|
|
|
|
val.function = GXcopy;
|
|
|
|
gc_mask = GCForeground | GCBackground | GCFunction;
|
|
|
|
gc = XCreateGC( dpy, mainW, gc_mask, &val );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* create the icon pixmap for desktops
|
|
|
|
*/
|
|
|
|
CreateIcon();
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* create the display
|
|
|
|
*/
|
|
|
|
CreateDispWindow();
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
/*
|
|
|
|
* create the keypad
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* draw the nice labels around the buttons
|
|
|
|
*/
|
|
|
|
keypad.width = width;
|
|
|
|
keypad.height = height;
|
|
|
|
|
|
|
|
keypad.pixmap = XCreatePixmap( dpy, mainW, width, height, depth );
|
|
|
|
|
|
|
|
if ( netbook ) {
|
|
|
|
int cut =
|
|
|
|
buttons[ BUTTON_MTH ].y - ( small_ascent + small_descent + 6 + 4 );
|
|
|
|
CreateBackground( width / 2, height, width, height, &keypad );
|
|
|
|
DrawMore( width, height, KEYBOARD_OFFSET_Y, KEYBOARD_OFFSET_X,
|
|
|
|
&keypad );
|
|
|
|
CreateBezel( width / 2, height, KEYBOARD_OFFSET_Y, KEYBOARD_OFFSET_X,
|
|
|
|
&keypad );
|
|
|
|
CreateKeypad( width, height, -cut, KEYBOARD_OFFSET_X, &keypad );
|
|
|
|
} else {
|
|
|
|
int cut = buttons[ BUTTON_MTH ].y + KEYBOARD_OFFSET_Y - 19;
|
|
|
|
CreateBackground( width, cut, width, height, &keypad );
|
|
|
|
DrawMore( width, height, KEYBOARD_OFFSET_Y, KEYBOARD_OFFSET_X,
|
|
|
|
&keypad );
|
|
|
|
CreateBezel( width, cut, KEYBOARD_OFFSET_Y, KEYBOARD_OFFSET_X,
|
|
|
|
&keypad );
|
|
|
|
CreateKeypad( width, height, KEYBOARD_OFFSET_Y, KEYBOARD_OFFSET_X,
|
|
|
|
&keypad );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* map the window
|
|
|
|
*/
|
|
|
|
XMapWindow( dpy, mainW );
|
|
|
|
XMapSubwindows( dpy, mainW );
|
|
|
|
|
|
|
|
DrawKeypad( &keypad );
|
|
|
|
DrawButtons();
|
|
|
|
DrawIcon();
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( shm_flag ) {
|
|
|
|
XSetForeground( dpy, disp.gc, COLOR( PIXEL ) );
|
|
|
|
XFillRectangle( dpy, disp.win, disp.gc, 5, 20, 262, 128 );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void ShowConnections( char* wire, char* ir ) {
|
|
|
|
int x, y, w, h;
|
|
|
|
int conn_top;
|
|
|
|
XFontStruct* finfo;
|
|
|
|
char name[ 128 ];
|
|
|
|
XGCValues val;
|
|
|
|
unsigned long gc_mask;
|
|
|
|
XCharStruct xchar;
|
|
|
|
int dir, fa, fd;
|
|
|
|
Pixmap pix;
|
|
|
|
|
|
|
|
finfo = get_font_resource( dpy, "connectionFont", "ConnectionFont" );
|
|
|
|
val.font = finfo->fid;
|
|
|
|
gc_mask = GCFont;
|
|
|
|
XChangeGC( dpy, gc, gc_mask, &val );
|
|
|
|
|
|
|
|
conn_top = DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 18;
|
|
|
|
|
|
|
|
XTextExtents( finfo, "TEST", ( int )strlen( "TEST" ), &dir, &fa, &fd,
|
|
|
|
&xchar );
|
|
|
|
w = DISPLAY_WIDTH;
|
|
|
|
h = fa + fd;
|
|
|
|
|
|
|
|
pix = XCreatePixmap( dpy, keypad.pixmap, w, h, depth ); /* FIXME keypad? */
|
|
|
|
XSetForeground( dpy, gc, COLOR( DISP_PAD ) );
|
|
|
|
XFillRectangle( dpy, pix, gc, 0, 0, w, h );
|
|
|
|
|
|
|
|
XSetBackground( dpy, gc, COLOR( DISP_PAD ) );
|
|
|
|
XSetForeground( dpy, gc, COLOR( LABEL ) );
|
|
|
|
|
|
|
|
sprintf( name, "wire: %s", wire ? wire : "none" );
|
|
|
|
XTextExtents( finfo, name, ( int )strlen( name ), &dir, &fa, &fd, &xchar );
|
|
|
|
x = 0;
|
|
|
|
y = fa;
|
|
|
|
XDrawImageString( dpy, pix, gc, x, y, name, ( int )strlen( name ) );
|
|
|
|
|
|
|
|
sprintf( name, "IR: %s", ir ? ir : "none" );
|
|
|
|
XTextExtents( finfo, name, ( int )strlen( name ), &dir, &fa, &fd, &xchar );
|
|
|
|
x = w - xchar.width - 1;
|
|
|
|
y = fa;
|
|
|
|
XDrawImageString( dpy, pix, gc, x, y, name, ( int )strlen( name ) );
|
|
|
|
|
|
|
|
x = DISPLAY_OFFSET_X;
|
|
|
|
y = conn_top;
|
|
|
|
XCopyArea( dpy, pix, keypad.pixmap, gc, 0, 0, w, h, x,
|
|
|
|
y ); /* FIXME keypad? */
|
|
|
|
|
|
|
|
DrawKeypad( &keypad );
|
|
|
|
|
|
|
|
XFreePixmap( dpy, pix );
|
|
|
|
XFreeFont( dpy, finfo );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int button_pressed( int b ) {
|
|
|
|
int code;
|
|
|
|
int i, r, c;
|
|
|
|
|
|
|
|
code = buttons[ b ].code;
|
|
|
|
buttons[ b ].pressed = 1;
|
|
|
|
if ( code == 0x8000 ) {
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
saturn.keybuf.rows[ i ] |= 0x8000;
|
2015-07-26 11:16:05 +02:00
|
|
|
do_kbd_int();
|
2023-04-27 12:15:59 +02:00
|
|
|
} else {
|
|
|
|
r = code >> 4;
|
|
|
|
c = 1 << ( code & 0xf );
|
|
|
|
if ( ( saturn.keybuf.rows[ r ] & c ) == 0 ) {
|
|
|
|
if ( saturn.kbd_ien ) {
|
|
|
|
do_kbd_int();
|
|
|
|
}
|
|
|
|
if ( ( saturn.keybuf.rows[ r ] & c ) ) {
|
|
|
|
fprintf( stderr, "bug\n" );
|
|
|
|
}
|
|
|
|
saturn.keybuf.rows[ r ] |= c;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
#ifdef DEBUG_BUTTONS
|
2023-04-27 12:15:59 +02:00
|
|
|
fprintf( stderr, "Button pressed %d (%s)\n", buttons[ b ].code,
|
|
|
|
buttons[ b ].name );
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int button_released( int b ) {
|
|
|
|
int code;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
code = buttons[ b ].code;
|
|
|
|
buttons[ b ].pressed = 0;
|
|
|
|
if ( code == 0x8000 ) {
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
saturn.keybuf.rows[ i ] &= ~0x8000;
|
|
|
|
} else {
|
|
|
|
int r, c;
|
|
|
|
r = code >> 4;
|
|
|
|
c = 1 << ( code & 0xf );
|
|
|
|
saturn.keybuf.rows[ r ] &= ~c;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef DEBUG_BUTTONS
|
2023-04-27 12:15:59 +02:00
|
|
|
fprintf( stderr, "Button released %d (%s)\n", buttons[ b ].code,
|
|
|
|
buttons[ b ].name );
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
static int button_release_all( void ) {
|
|
|
|
int code;
|
|
|
|
int b;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
#ifdef DEBUG_BUTTONS
|
2023-04-27 12:15:59 +02:00
|
|
|
fprintf( stderr, "Buttons released " );
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
for ( b = BUTTON_A; b <= LAST_BUTTON; b++ ) {
|
|
|
|
if ( buttons[ b ].pressed ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef DEBUG_BUTTONS
|
2023-04-27 12:15:59 +02:00
|
|
|
fprintf( stderr, "%d (%s) ", buttons[ b ].code, buttons[ b ].name );
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
code = buttons[ b ].code;
|
|
|
|
if ( code == 0x8000 ) {
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
saturn.keybuf.rows[ i ] &= ~0x8000;
|
|
|
|
} else {
|
|
|
|
int r, c;
|
|
|
|
r = code >> 4;
|
|
|
|
c = 1 << ( code & 0xf );
|
|
|
|
saturn.keybuf.rows[ r ] &= ~c;
|
|
|
|
}
|
|
|
|
buttons[ b ].pressed = 0;
|
|
|
|
DrawButton( b );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
#ifdef DEBUG_BUTTONS
|
2023-04-27 12:15:59 +02:00
|
|
|
fprintf( stderr, "\n" );
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int key_event( int b, XEvent* xev ) {
|
|
|
|
int code;
|
|
|
|
int i, r, c;
|
2023-04-27 13:31:46 +02:00
|
|
|
// int all_up;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
code = buttons[ b ].code;
|
|
|
|
if ( xev->type == KeyPress ) {
|
|
|
|
buttons[ b ].pressed = 1;
|
|
|
|
DrawButton( b );
|
|
|
|
if ( code == 0x8000 ) {
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
saturn.keybuf.rows[ i ] |= 0x8000;
|
|
|
|
do_kbd_int();
|
|
|
|
} else {
|
|
|
|
r = code >> 4;
|
|
|
|
c = 1 << ( code & 0xf );
|
|
|
|
if ( ( saturn.keybuf.rows[ r ] & c ) == 0 ) {
|
|
|
|
if ( saturn.kbd_ien ) {
|
|
|
|
do_kbd_int();
|
|
|
|
}
|
|
|
|
saturn.keybuf.rows[ r ] |= c;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
#ifdef DEBUG_BUTTONS
|
2023-04-27 12:15:59 +02:00
|
|
|
fprintf( stderr, "Key pressed %d (%s) %x\n", buttons[ b ].code,
|
|
|
|
buttons[ b ].name ),
|
|
|
|
c;
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2022-03-24 13:41:22 +01:00
|
|
|
} else {
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( code == 0x8000 ) {
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
saturn.keybuf.rows[ i ] &= ~0x8000;
|
|
|
|
memset( &saturn.keybuf, 0, sizeof( saturn.keybuf ) );
|
|
|
|
} else {
|
|
|
|
r = code >> 4;
|
|
|
|
c = 1 << ( code & 0xf );
|
|
|
|
saturn.keybuf.rows[ r ] &= ~c;
|
|
|
|
}
|
|
|
|
buttons[ b ].pressed = 0;
|
|
|
|
DrawButton( b );
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef DEBUG_BUTTONS
|
2023-04-27 12:15:59 +02:00
|
|
|
fprintf( stderr, "Key released %d (%s)\n", buttons[ b ].code,
|
|
|
|
buttons[ b ].name );
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
|
|
|
return 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
void refresh_display( void ) {
|
|
|
|
if ( shm_flag ) {
|
|
|
|
if ( disp.display_update & UPDATE_DISP ) {
|
|
|
|
XShmPutImage( dpy, disp.win, disp.gc, disp.disp_image, disp.offset,
|
|
|
|
0, 5, 20, 262, ( unsigned int )( disp.lines + 2 ),
|
|
|
|
0 );
|
|
|
|
}
|
|
|
|
if ( ( disp.lines < 126 ) && ( disp.display_update & UPDATE_MENU ) ) {
|
|
|
|
XShmPutImage( dpy, disp.win, disp.gc, disp.menu_image, 0, 0, 5,
|
|
|
|
( int )( disp.lines + 22 ), 262,
|
|
|
|
( unsigned int )( 126 - disp.lines ), 0 );
|
|
|
|
}
|
|
|
|
disp.display_update = 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void DrawDisp( void ) {
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( shm_flag ) {
|
|
|
|
XShmPutImage( dpy, disp.win, disp.gc, disp.disp_image, disp.offset, 0,
|
|
|
|
5, 20, 262, ( unsigned int )( disp.lines + 2 ), 0 );
|
|
|
|
if ( display.lines < 63 ) {
|
|
|
|
XShmPutImage( dpy, disp.win, disp.gc, disp.menu_image, 0,
|
|
|
|
disp.lines - 110, 5, 22 + disp.lines, 262,
|
|
|
|
( unsigned int )( 126 - disp.lines ), 0 );
|
|
|
|
}
|
|
|
|
disp.display_update = 0;
|
|
|
|
} else {
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
redraw_display();
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef HAVE_XSHM
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
redraw_annunc();
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void get_geometry_string( Window win, char* s, int allow_off_screen ) {
|
|
|
|
XWindowAttributes xwa;
|
|
|
|
Window root, parent, window;
|
|
|
|
Window* children = ( Window* )0;
|
|
|
|
unsigned int rw, rh, rbw, rd;
|
|
|
|
unsigned int w, h, bw, d;
|
|
|
|
unsigned int nc;
|
|
|
|
int rx, ry, x, y;
|
|
|
|
int x_pos, x_neg, x_s, y_pos, y_neg, y_s;
|
|
|
|
|
|
|
|
window = win;
|
2022-03-24 13:41:22 +01:00
|
|
|
nc = 0;
|
2023-04-27 12:15:59 +02:00
|
|
|
XQueryTree( dpy, window, &root, &parent, &children, &nc );
|
|
|
|
XFree( ( char* )children );
|
|
|
|
while ( parent != root ) {
|
|
|
|
window = parent;
|
|
|
|
nc = 0;
|
|
|
|
XQueryTree( dpy, window, &root, &parent, &children, &nc );
|
|
|
|
XFree( ( char* )children );
|
|
|
|
}
|
|
|
|
XGetGeometry( dpy, window, &root, &x, &y, &w, &h, &bw, &d );
|
|
|
|
XGetGeometry( dpy, root, &root, &rx, &ry, &rw, &rh, &rbw, &rd );
|
|
|
|
|
|
|
|
x_s = 1;
|
|
|
|
x_pos = x;
|
|
|
|
x_neg = rw - ( x + w );
|
|
|
|
if ( abs( x_pos ) > abs( x_neg ) ) {
|
|
|
|
x = x_neg;
|
|
|
|
x_s = -1;
|
|
|
|
}
|
|
|
|
y_s = 1;
|
|
|
|
y_pos = y;
|
|
|
|
y_neg = rh - ( y + h );
|
|
|
|
if ( abs( y_pos ) > abs( y_neg ) ) {
|
|
|
|
y = y_neg;
|
|
|
|
y_s = -1;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
if ( !allow_off_screen ) {
|
|
|
|
if ( x < 0 )
|
|
|
|
x = 0;
|
|
|
|
if ( y < 0 )
|
|
|
|
y = 0;
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XGetWindowAttributes( dpy, win, &xwa );
|
|
|
|
sprintf( s, "%ux%u%s%d%s%d", xwa.width, xwa.height, ( x_s > 0 ) ? "+" : "-",
|
|
|
|
x, ( y_s > 0 ) ? "+" : "-", y );
|
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void save_command_line( void ) {
|
|
|
|
XWindowAttributes xwa;
|
|
|
|
int wm_argc, ac;
|
|
|
|
char **wm_argv, geom[ 128 ], icon_geom[ 128 ];
|
|
|
|
|
|
|
|
ac = wm_argc = 0;
|
|
|
|
|
|
|
|
wm_argv = ( char** )malloc( ( saved_argc + 5 ) * sizeof( char* ) );
|
|
|
|
if ( wm_argv == ( char** )0 ) {
|
|
|
|
if ( !quiet )
|
|
|
|
fprintf( stderr,
|
|
|
|
"%s: warning: malloc failed in wm_save_yourself.\n",
|
|
|
|
progname );
|
|
|
|
XSetCommand( dpy, mainW, saved_argv, saved_argc );
|
|
|
|
return;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
|
|
|
while ( saved_argv[ ac ] ) {
|
|
|
|
if ( !strcmp( saved_argv[ ac ], "-geometry" ) ) {
|
|
|
|
ac += 2;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( !strcmp( saved_argv[ ac ], "-iconGeom" ) ) {
|
|
|
|
ac += 2;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( !strcmp( saved_argv[ ac ], "-iconic" ) ) {
|
|
|
|
ac++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
wm_argv[ wm_argc++ ] = saved_argv[ ac++ ];
|
2022-03-24 13:41:22 +01:00
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
wm_argv[ wm_argc++ ] = "-geometry";
|
|
|
|
get_geometry_string( mainW, geom, 1 );
|
|
|
|
wm_argv[ wm_argc++ ] = geom;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
wm_argv[ wm_argc++ ] = "-iconGeom";
|
|
|
|
get_geometry_string( iconW, icon_geom, 0 );
|
|
|
|
wm_argv[ wm_argc++ ] = icon_geom;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XGetWindowAttributes( dpy, mainW, &xwa );
|
|
|
|
if ( xwa.map_state == IsUnmapped ) {
|
|
|
|
wm_argv[ wm_argc++ ] = "-iconic";
|
|
|
|
}
|
|
|
|
wm_argv[ wm_argc ] = ( char* )0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
XSetCommand( dpy, mainW, wm_argv, wm_argc );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
void exit_x48( int tell_x11 ) {
|
|
|
|
exit_emulator();
|
|
|
|
if ( tell_x11 )
|
|
|
|
XCloseDisplay( dpy );
|
|
|
|
exit( 0 );
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
int decode_key( XEvent* xev, KeySym sym, char* buf, int buflen ) {
|
|
|
|
int wake;
|
2022-03-24 13:41:22 +01:00
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
wake = 0;
|
|
|
|
if ( buflen == 1 )
|
|
|
|
switch ( buf[ 0 ] ) {
|
|
|
|
case '0':
|
|
|
|
sym = XK_0;
|
|
|
|
break;
|
|
|
|
case '1':
|
|
|
|
sym = XK_1;
|
|
|
|
break;
|
|
|
|
case '2':
|
|
|
|
sym = XK_2;
|
|
|
|
break;
|
|
|
|
case '3':
|
|
|
|
sym = XK_3;
|
|
|
|
break;
|
|
|
|
case '4':
|
|
|
|
sym = XK_4;
|
|
|
|
break;
|
|
|
|
case '5':
|
|
|
|
sym = XK_5;
|
|
|
|
break;
|
|
|
|
case '6':
|
|
|
|
sym = XK_6;
|
|
|
|
break;
|
|
|
|
case '7':
|
|
|
|
sym = XK_7;
|
|
|
|
break;
|
|
|
|
case '8':
|
|
|
|
sym = XK_8;
|
|
|
|
break;
|
|
|
|
case '9':
|
|
|
|
sym = XK_9;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch ( ( int )sym ) {
|
|
|
|
case XK_KP_0:
|
|
|
|
case XK_0:
|
|
|
|
key_event( BUTTON_0, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_1:
|
|
|
|
case XK_1:
|
|
|
|
key_event( BUTTON_1, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_2:
|
|
|
|
case XK_2:
|
|
|
|
key_event( BUTTON_2, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_3:
|
|
|
|
case XK_3:
|
|
|
|
key_event( BUTTON_3, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_4:
|
|
|
|
case XK_4:
|
|
|
|
key_event( BUTTON_4, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_5:
|
|
|
|
case XK_5:
|
|
|
|
key_event( BUTTON_5, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_6:
|
|
|
|
case XK_6:
|
|
|
|
key_event( BUTTON_6, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_7:
|
|
|
|
case XK_7:
|
|
|
|
key_event( BUTTON_7, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_8:
|
|
|
|
case XK_8:
|
|
|
|
key_event( BUTTON_8, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_9:
|
|
|
|
case XK_9:
|
|
|
|
key_event( BUTTON_9, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_Add:
|
|
|
|
case XK_plus:
|
|
|
|
case XK_equal:
|
|
|
|
key_event( BUTTON_PLUS, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_Subtract:
|
|
|
|
case XK_minus:
|
|
|
|
key_event( BUTTON_MINUS, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef XK_F25
|
2023-04-27 12:15:59 +02:00
|
|
|
case XK_F25:
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
case XK_KP_Divide:
|
|
|
|
case XK_slash:
|
|
|
|
key_event( BUTTON_DIV, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
2015-07-26 11:16:05 +02:00
|
|
|
#ifdef XK_F26
|
2023-04-27 12:15:59 +02:00
|
|
|
case XK_F26:
|
2015-07-26 11:16:05 +02:00
|
|
|
#endif
|
2023-04-27 12:15:59 +02:00
|
|
|
case XK_KP_Multiply:
|
|
|
|
case XK_asterisk:
|
|
|
|
case XK_comma:
|
|
|
|
key_event( BUTTON_MUL, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_Enter:
|
|
|
|
case XK_Return:
|
|
|
|
key_event( BUTTON_ENTER, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_KP_Decimal:
|
|
|
|
case XK_KP_Separator:
|
|
|
|
case XK_period:
|
|
|
|
key_event( BUTTON_PERIOD, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_space:
|
|
|
|
key_event( BUTTON_SPC, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_Delete:
|
|
|
|
key_event( BUTTON_DEL, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_BackSpace:
|
|
|
|
key_event( BUTTON_BS, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_Escape:
|
|
|
|
key_event( BUTTON_ON, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_Shift_L:
|
|
|
|
case XK_Control_R:
|
|
|
|
key_event( BUTTON_SHL, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_Shift_R:
|
|
|
|
case XK_Control_L:
|
|
|
|
key_event( BUTTON_SHR, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_Alt_L:
|
|
|
|
case XK_Alt_R:
|
|
|
|
case XK_Meta_L:
|
|
|
|
case XK_Meta_R:
|
|
|
|
key_event( BUTTON_ALPHA, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_a:
|
|
|
|
case XK_A:
|
|
|
|
case XK_F1:
|
|
|
|
key_event( BUTTON_A, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_b:
|
|
|
|
case XK_B:
|
|
|
|
case XK_F2:
|
|
|
|
key_event( BUTTON_B, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_c:
|
|
|
|
case XK_C:
|
|
|
|
case XK_F3:
|
|
|
|
key_event( BUTTON_C, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_d:
|
|
|
|
case XK_D:
|
|
|
|
case XK_F4:
|
|
|
|
key_event( BUTTON_D, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_e:
|
|
|
|
case XK_E:
|
|
|
|
case XK_F5:
|
|
|
|
key_event( BUTTON_E, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_f:
|
|
|
|
case XK_F:
|
|
|
|
case XK_F6:
|
|
|
|
key_event( BUTTON_F, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_g:
|
|
|
|
case XK_G:
|
|
|
|
key_event( BUTTON_MTH, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_h:
|
|
|
|
case XK_H:
|
|
|
|
key_event( BUTTON_PRG, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_i:
|
|
|
|
case XK_I:
|
|
|
|
key_event( BUTTON_CST, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_j:
|
|
|
|
case XK_J:
|
|
|
|
key_event( BUTTON_VAR, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_k:
|
|
|
|
case XK_K:
|
|
|
|
case XK_Up:
|
|
|
|
key_event( BUTTON_UP, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_l:
|
|
|
|
case XK_L:
|
|
|
|
key_event( BUTTON_NXT, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_m:
|
|
|
|
case XK_M:
|
|
|
|
key_event( BUTTON_COLON, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_n:
|
|
|
|
case XK_N:
|
|
|
|
key_event( BUTTON_STO, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_o:
|
|
|
|
case XK_O:
|
|
|
|
key_event( BUTTON_EVAL, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_p:
|
|
|
|
case XK_P:
|
|
|
|
case XK_Left:
|
|
|
|
key_event( BUTTON_LEFT, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_q:
|
|
|
|
case XK_Q:
|
|
|
|
case XK_Down:
|
|
|
|
key_event( BUTTON_DOWN, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_r:
|
|
|
|
case XK_R:
|
|
|
|
case XK_Right:
|
|
|
|
key_event( BUTTON_RIGHT, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_s:
|
|
|
|
case XK_S:
|
|
|
|
key_event( BUTTON_SIN, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_t:
|
|
|
|
case XK_T:
|
|
|
|
key_event( BUTTON_COS, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_u:
|
|
|
|
case XK_U:
|
|
|
|
key_event( BUTTON_TAN, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_v:
|
|
|
|
case XK_V:
|
|
|
|
key_event( BUTTON_SQRT, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_w:
|
|
|
|
case XK_W:
|
|
|
|
key_event( BUTTON_POWER, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_x:
|
|
|
|
case XK_X:
|
|
|
|
key_event( BUTTON_INV, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_y:
|
|
|
|
case XK_Y:
|
|
|
|
key_event( BUTTON_NEG, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
case XK_z:
|
|
|
|
case XK_Z:
|
|
|
|
key_event( BUTTON_EEX, xev );
|
|
|
|
wake = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return wake;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_PASTE 128
|
2023-04-27 12:15:59 +02:00
|
|
|
int paste[ MAX_PASTE * 3 ];
|
2022-03-24 13:41:22 +01:00
|
|
|
int paste_count = 0;
|
|
|
|
int paste_size = 0;
|
|
|
|
int paste_last_key = 0;
|
2015-07-26 11:16:05 +02:00
|
|
|
|
|
|
|
int first_key = 0;
|
|
|
|
|
|
|
|
int last_button = -1;
|
|
|
|
|
2023-04-27 12:15:59 +02:00
|
|
|
extern char* get_stack( void );
|
2023-05-03 09:40:52 +02:00
|
|
|
#elif defined( GUI_IS_SDL1 )
|
|
|
|
void SDLCreateHP() {
|
|
|
|
/* int x, y, w, h; */
|
|
|
|
unsigned int width, height;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// SDL port: we allocate memory for the buttons because we need to modify
|
|
|
|
// their coordinates, and we don't want to change the original buttons_gx or
|
|
|
|
// buttons_sx
|
|
|
|
if ( buttons ) {
|
|
|
|
free( buttons );
|
|
|
|
buttons = 0;
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
buttons = ( button_t* )malloc( sizeof( buttons_gx ) );
|
2022-03-24 11:19:16 +01:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( opt_gx ) {
|
|
|
|
// buttons = buttons_gx;
|
|
|
|
memcpy( buttons, buttons_gx, sizeof( buttons_gx ) );
|
|
|
|
colors = colors_gx;
|
|
|
|
} else {
|
|
|
|
// buttons = buttons_sx;
|
|
|
|
memcpy( buttons, buttons_sx, sizeof( buttons_sx ) );
|
|
|
|
colors = colors_sx;
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
2022-03-24 11:19:16 +01:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
int cut;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
///////////////////////////////////////////////
|
|
|
|
// SDL PORT
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
SDLCreateColors();
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
width = KEYBOARD_WIDTH + 2 * SIDE_SKIP;
|
|
|
|
height = DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + DISP_KBD_SKIP +
|
|
|
|
KEYBOARD_HEIGHT + BOTTOM_SKIP;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
disp.mapped = 1;
|
|
|
|
disp.w = DISPLAY_WIDTH;
|
|
|
|
disp.h = DISPLAY_HEIGHT;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
keypad.width = width;
|
|
|
|
keypad.height = height;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
printf( "Screen size: %d %d\n", width, height );
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
cut = buttons[ BUTTON_MTH ].y + KEYBOARD_OFFSET_Y - 19;
|
|
|
|
SDLDrawBackground( width, cut, width, height );
|
|
|
|
SDLDrawMore( width, height, cut, KEYBOARD_OFFSET_Y, KEYBOARD_OFFSET_X,
|
|
|
|
keypad.width, keypad.height );
|
|
|
|
SDLDrawLogo( width, height, cut, KEYBOARD_OFFSET_Y, KEYBOARD_OFFSET_X,
|
|
|
|
keypad.width, keypad.height );
|
|
|
|
SDLDrawBezel( width, height, KEYBOARD_OFFSET_Y, KEYBOARD_OFFSET_X );
|
|
|
|
SDLDrawKeypad();
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_UpdateRect( sdlwindow, 0, 0, 0, 0 );
|
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void ShowConnections( char* wire, char* ir ) {
|
|
|
|
printf( "ShowConnections: Not Implemented\n" );
|
|
|
|
/*
|
|
|
|
int x, y, w, h;
|
|
|
|
int conn_top;
|
|
|
|
XFontStruct *finfo;
|
|
|
|
char name[128];
|
|
|
|
XGCValues val;
|
|
|
|
unsigned long gc_mask;
|
|
|
|
XCharStruct xchar;
|
|
|
|
int dir, fa, fd;
|
|
|
|
Pixmap pix;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
finfo = get_font_resource(dpy, "connectionFont", "ConnectionFont");
|
|
|
|
val.font = finfo->fid;
|
|
|
|
gc_mask = GCFont;
|
|
|
|
XChangeGC(dpy, gc, gc_mask, &val);
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
conn_top = DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + 18;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
XTextExtents(finfo, "TEST", (int)strlen("TEST"), &dir, &fa, &fd, &xchar);
|
|
|
|
w = DISPLAY_WIDTH;
|
|
|
|
h = fa + fd;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
pix = XCreatePixmap(dpy, keypad.pixmap, w, h, depth); // FIXME
|
|
|
|
keypad? XSetForeground(dpy, gc, COLOR(DISP_PAD)); XFillRectangle(dpy, pix, gc,
|
|
|
|
0, 0, w, h);
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
XSetBackground(dpy, gc, COLOR(DISP_PAD));
|
|
|
|
XSetForeground(dpy, gc, COLOR(LABEL));
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
sprintf(name, "wire: %s", wire ? wire : "none");
|
|
|
|
XTextExtents(finfo, name, (int)strlen(name), &dir, &fa, &fd, &xchar);
|
|
|
|
x = 0;
|
|
|
|
y = fa;
|
|
|
|
XDrawImageString(dpy, pix, gc, x, y, name, (int)strlen(name));
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
sprintf(name, "IR: %s", ir ? ir : "none");
|
|
|
|
XTextExtents(finfo, name, (int)strlen(name), &dir, &fa, &fd, &xchar);
|
|
|
|
x = w - xchar.width - 1;
|
|
|
|
y = fa;
|
|
|
|
XDrawImageString(dpy, pix, gc, x, y, name, (int)strlen(name));
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = DISPLAY_OFFSET_X;
|
|
|
|
y = conn_top;
|
|
|
|
XCopyArea(dpy, pix, keypad.pixmap, gc, 0, 0, w, h, x, y); // FIXME
|
|
|
|
keypad?
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
DrawKeypad(&keypad);
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
XFreePixmap(dpy, pix);
|
|
|
|
XFreeFont(dpy, finfo);*/
|
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
int button_pressed( int b ) {
|
|
|
|
int code;
|
|
|
|
int i, r, c;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( buttons[ b ].pressed == 1 ) // Check not already pressed (may be
|
|
|
|
// important: avoids a useless do_kbd_int)
|
|
|
|
return 0;
|
|
|
|
buttons[ b ].pressed = 1;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
code = buttons[ b ].code;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( code == 0x8000 ) {
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
saturn.keybuf.rows[ i ] |= 0x8000;
|
|
|
|
do_kbd_int();
|
|
|
|
} else {
|
|
|
|
r = code >> 4;
|
|
|
|
c = 1 << ( code & 0xf );
|
|
|
|
if ( ( saturn.keybuf.rows[ r ] & c ) == 0 ) {
|
|
|
|
if ( saturn.kbd_ien ) {
|
|
|
|
do_kbd_int();
|
|
|
|
}
|
|
|
|
#ifdef DEBUG_BUTTONS
|
|
|
|
if ( ( saturn.keybuf.rows[ r ] & c ) ) {
|
|
|
|
fprintf( stderr, "bug\n" );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
saturn.keybuf.rows[ r ] |= c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef DEBUG_BUTTONS
|
|
|
|
fprintf( stderr, "Button pressed %d (%s)\n", buttons[ b ].code,
|
|
|
|
buttons[ b ].name );
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int button_released( int b ) {
|
|
|
|
int code;
|
|
|
|
|
|
|
|
if ( buttons[ b ].pressed ==
|
|
|
|
0 ) // Check not already released (not critical)
|
|
|
|
return 0;
|
|
|
|
buttons[ b ].pressed = 0;
|
|
|
|
|
|
|
|
code = buttons[ b ].code;
|
|
|
|
if ( code == 0x8000 ) {
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < 9; i++ )
|
|
|
|
saturn.keybuf.rows[ i ] &= ~0x8000;
|
|
|
|
} else {
|
|
|
|
int r, c;
|
|
|
|
r = code >> 4;
|
|
|
|
c = 1 << ( code & 0xf );
|
|
|
|
saturn.keybuf.rows[ r ] &= ~c;
|
|
|
|
}
|
|
|
|
#ifdef DEBUG_BUTTONS
|
|
|
|
fprintf( stderr, "Button released %d (%s)\n", buttons[ b ].code,
|
|
|
|
buttons[ b ].name );
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
static int button_release_all( void ) {
|
|
|
|
int b;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for ( b = BUTTON_A; b <= LAST_BUTTON; b++ )
|
|
|
|
if ( buttons[ b ].pressed )
|
|
|
|
button_released( b );
|
|
|
|
return 0;
|
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
/* void DrawDisp( void ) { */
|
|
|
|
/* redraw_display(); */
|
|
|
|
/* redraw_annunc(); */
|
|
|
|
/* } */
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void exit_x48( int tell_x11 ) {
|
|
|
|
exit_emulator();
|
|
|
|
// if (tell_x11)
|
|
|
|
// XCloseDisplay(dpy);
|
|
|
|
exit( 0 );
|
|
|
|
}
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
#define MAX_PASTE 128
|
|
|
|
int paste[ MAX_PASTE * 3 ];
|
|
|
|
int paste_count = 0;
|
|
|
|
int paste_size = 0;
|
|
|
|
int paste_last_key = 0;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
int first_key = 0;
|
2023-04-27 12:15:59 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
int last_button = -1;
|
2022-03-24 11:19:16 +01:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
extern char* get_stack( void );
|
2015-07-26 11:16:05 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Find which key is pressed, if any.
|
|
|
|
// Returns -1 is no key is pressed
|
|
|
|
int SDLCoordinateToKey( int x, int y ) {
|
|
|
|
int i;
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
|
|
|
if ( x >= KEYBOARD_OFFSET_X + buttons[ i ].x &&
|
|
|
|
x <= KEYBOARD_OFFSET_X + buttons[ i ].x + buttons[ i ].w &&
|
|
|
|
y >= KEYBOARD_OFFSET_Y + buttons[ i ].y &&
|
|
|
|
y <= KEYBOARD_OFFSET_Y + buttons[ i ].y + buttons[ i ].h ) {
|
|
|
|
return i;
|
2023-04-27 12:15:59 +02:00
|
|
|
}
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
return -1;
|
2015-07-26 11:16:05 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
// Map the keyboard keys to the HP keys
|
|
|
|
// Returns -1 if there is no mapping
|
|
|
|
int SDLKeyToKey( SDLKey k ) {
|
|
|
|
int i;
|
|
|
|
i = 0;
|
|
|
|
while ( sdltohpkeymap[ i ].sdlkey ) {
|
|
|
|
if ( sdltohpkeymap[ i ].sdlkey == k )
|
|
|
|
return sdltohpkeymap[ i ].hpkey;
|
|
|
|
i++;
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLDrawMore( unsigned int w, unsigned int h, unsigned int cut,
|
|
|
|
unsigned int offset_y, unsigned int offset_x,
|
|
|
|
int keypad_width, int keypad_height ) {
|
|
|
|
/* int x, y; */
|
|
|
|
/* SDL_Surface *surf; */
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
int display_height = DISPLAY_HEIGHT;
|
|
|
|
int display_width = DISPLAY_WIDTH;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
printf( "display: %d %d\n", display_height, display_width );
|
|
|
|
printf( "keypad: %d %d\n", keypad_height, keypad_width );
|
|
|
|
printf( "wh: %d %d\n", w, h );
|
|
|
|
printf( "cut: %d\n", cut );
|
|
|
|
printf( "offset: %d %d\n", offset_y, offset_x );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// lower the whole thing
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// bottom lines
|
|
|
|
lineColor( sdlwindow, 1, keypad_height - 1, keypad_width - 1,
|
|
|
|
keypad_height - 1, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, 2, keypad_height - 2, keypad_width - 2,
|
|
|
|
keypad_height - 2, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// right lines
|
|
|
|
lineColor( sdlwindow, keypad_width - 1, keypad_height - 1, keypad_width - 1,
|
|
|
|
cut, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, keypad_width - 2, keypad_height - 2, keypad_width - 2,
|
|
|
|
cut, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// right lines
|
|
|
|
lineColor( sdlwindow, keypad_width - 1, cut - 1, keypad_width - 1, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, keypad_width - 2, cut - 1, keypad_width - 2, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// top lines
|
|
|
|
lineColor( sdlwindow, 0, 0, keypad_width - 2, 0,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 1, 1, keypad_width - 3, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// left lines
|
|
|
|
lineColor( sdlwindow, 0, cut - 1, 0, 0,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 1, cut - 1, 1, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// left lines
|
|
|
|
lineColor( sdlwindow, 0, keypad_height - 2, 0, cut,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 1, keypad_height - 3, 1, cut,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// lower the menu buttons
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// bottom lines
|
|
|
|
lineColor( sdlwindow, 3, keypad_height - 3, keypad_width - 3,
|
|
|
|
keypad_height - 3, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, 4, keypad_height - 4, keypad_width - 4,
|
|
|
|
keypad_height - 4, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// right lines
|
|
|
|
lineColor( sdlwindow, keypad_width - 3, keypad_height - 3, keypad_width - 3,
|
|
|
|
cut, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, keypad_width - 4, keypad_height - 4, keypad_width - 4,
|
|
|
|
cut, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// right lines
|
|
|
|
lineColor( sdlwindow, keypad_width - 3, cut - 1, keypad_width - 3,
|
|
|
|
offset_y - ( KBD_UPLINE - 1 ),
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, keypad_width - 4, cut - 1, keypad_width - 4,
|
|
|
|
offset_y - ( KBD_UPLINE - 2 ),
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// top lines
|
|
|
|
lineColor( sdlwindow, 2, offset_y - ( KBD_UPLINE - 0 ), keypad_width - 4,
|
|
|
|
offset_y - ( KBD_UPLINE - 0 ),
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 3, offset_y - ( KBD_UPLINE - 1 ), keypad_width - 5,
|
|
|
|
offset_y - ( KBD_UPLINE - 1 ),
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
|
|
|
|
// left lines
|
|
|
|
lineColor( sdlwindow, 2, cut - 1, 2, offset_y - ( KBD_UPLINE - 1 ),
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 3, cut - 1, 3, offset_y - ( KBD_UPLINE - 2 ),
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
|
|
|
|
// left lines
|
|
|
|
lineColor( sdlwindow, 2, keypad_height - 4, 2, cut,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 3, keypad_height - 5, 3, cut,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_BOT ] ) );
|
|
|
|
|
|
|
|
// lower the keyboard
|
|
|
|
|
|
|
|
// bottom lines
|
|
|
|
lineColor( sdlwindow, 5, keypad_height - 5, keypad_width - 3,
|
|
|
|
keypad_height - 5, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, 6, keypad_height - 6, keypad_width - 4,
|
|
|
|
keypad_height - 6, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
|
|
|
|
// right lines
|
|
|
|
lineColor( sdlwindow, keypad_width - 5, keypad_height - 5, keypad_width - 5,
|
|
|
|
cut + 1, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, keypad_width - 6, keypad_height - 6, keypad_width - 6,
|
|
|
|
cut + 2, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
|
|
|
|
// top lines
|
|
|
|
lineColor( sdlwindow, 4, cut, keypad_width - 6, cut,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 5, cut + 1, keypad_width - 7, cut + 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// left lines
|
|
|
|
lineColor( sdlwindow, 4, keypad_height - 6, 4, cut + 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 5, keypad_height - 7, 5, cut + 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// round off the bottom edge
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( sdlwindow, keypad_width - 7, keypad_height - 7, keypad_width - 7,
|
|
|
|
keypad_height - 14, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, keypad_width - 8, keypad_height - 8, keypad_width - 8,
|
|
|
|
keypad_height - 11, SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, keypad_width - 7, keypad_height - 7,
|
|
|
|
keypad_width - 14, keypad_height - 7,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, keypad_width - 7, keypad_height - 8,
|
|
|
|
keypad_width - 11, keypad_height - 8,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
pixelColor( sdlwindow, keypad_width - 9, keypad_height - 9,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( sdlwindow, 7, keypad_height - 7, 13, keypad_height - 7,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, 8, keypad_height - 8, 10, keypad_height - 8,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( sdlwindow, 6, keypad_height - 8, 6, keypad_height - 14,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, 7, keypad_height - 9, 7, keypad_height - 11,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ PAD_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLDrawLogo( unsigned int w, unsigned int h, unsigned int cut,
|
|
|
|
unsigned int offset_y, unsigned int offset_x,
|
|
|
|
int keypad_width, int keypad_height ) {
|
|
|
|
int x, y;
|
|
|
|
SDL_Surface* surf;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
/* int display_height = DISPLAY_HEIGHT; */
|
|
|
|
int display_width = DISPLAY_WIDTH;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// insert the HP Logo
|
|
|
|
surf = SDLCreateSurfFromData( hp_width, hp_height, hp_bits,
|
|
|
|
ARGBColors[ LOGO ], ARGBColors[ LOGO_BACK ] );
|
|
|
|
if ( opt_gx )
|
|
|
|
x = DISPLAY_OFFSET_X - 6;
|
|
|
|
else
|
|
|
|
x = DISPLAY_OFFSET_X;
|
|
|
|
SDL_Rect srect;
|
|
|
|
SDL_Rect drect;
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = hp_width;
|
|
|
|
srect.h = hp_height;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = 10;
|
|
|
|
drect.w = hp_width;
|
|
|
|
drect.h = hp_height;
|
|
|
|
SDL_BlitSurface( surf, &srect, sdlwindow, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( !opt_gx ) {
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X, 9,
|
|
|
|
DISPLAY_OFFSET_X + hp_width - 1, 9,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - 1, 10, DISPLAY_OFFSET_X - 1,
|
|
|
|
10 + hp_height - 1, SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X, 10 + hp_height,
|
|
|
|
DISPLAY_OFFSET_X + hp_width - 1, 10 + hp_height,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X + hp_width, 10,
|
|
|
|
DISPLAY_OFFSET_X + hp_width, 10 + hp_height - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// write the name of it
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( opt_gx ) {
|
|
|
|
x = DISPLAY_OFFSET_X + display_width - gx_128K_ram_width +
|
|
|
|
gx_128K_ram_x_hot + 2;
|
|
|
|
y = 10 + gx_128K_ram_y_hot;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
surf = SDLCreateSurfFromData( gx_128K_ram_width, gx_128K_ram_height,
|
|
|
|
gx_128K_ram_bits, ARGBColors[ LABEL ],
|
|
|
|
ARGBColors[ DISP_PAD ] );
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = gx_128K_ram_width;
|
|
|
|
srect.h = gx_128K_ram_height;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = y;
|
|
|
|
drect.w = gx_128K_ram_width;
|
|
|
|
drect.h = gx_128K_ram_height;
|
|
|
|
SDL_BlitSurface( surf, &srect, sdlwindow, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = DISPLAY_OFFSET_X + hp_width;
|
|
|
|
y = hp_height + 8 - hp48gx_height;
|
|
|
|
surf =
|
|
|
|
SDLCreateSurfFromData( hp48gx_width, hp48gx_height, hp48gx_bits,
|
|
|
|
ARGBColors[ LOGO ], ARGBColors[ DISP_PAD ] );
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = hp48gx_width;
|
|
|
|
srect.h = hp48gx_height;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = y;
|
|
|
|
drect.w = hp48gx_width;
|
|
|
|
drect.h = hp48gx_height;
|
|
|
|
SDL_BlitSurface( surf, &srect, sdlwindow, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = DISPLAY_OFFSET_X + DISPLAY_WIDTH - gx_128K_ram_width +
|
|
|
|
gx_silver_x_hot + 2;
|
|
|
|
y = 10 + gx_silver_y_hot;
|
|
|
|
surf = SDLCreateSurfFromData(
|
|
|
|
gx_silver_width, gx_silver_height, gx_silver_bits,
|
|
|
|
ARGBColors[ LOGO ],
|
|
|
|
0 ); // Background transparent: draw only silver line
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = gx_silver_width;
|
|
|
|
srect.h = gx_silver_height;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = y;
|
|
|
|
drect.w = gx_silver_width;
|
|
|
|
drect.h = gx_silver_height;
|
|
|
|
SDL_BlitSurface( surf, &srect, sdlwindow, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = DISPLAY_OFFSET_X + display_width - gx_128K_ram_width +
|
|
|
|
gx_green_x_hot + 2;
|
|
|
|
y = 10 + gx_green_y_hot;
|
|
|
|
surf = SDLCreateSurfFromData(
|
|
|
|
gx_green_width, gx_green_height, gx_green_bits, ARGBColors[ RIGHT ],
|
|
|
|
0 ); // Background transparent: draw only green menu
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = gx_green_width;
|
|
|
|
srect.h = gx_green_height;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = y;
|
|
|
|
drect.w = gx_green_width;
|
|
|
|
drect.h = gx_green_height;
|
|
|
|
SDL_BlitSurface( surf, &srect, sdlwindow, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
|
|
|
} else {
|
|
|
|
x = DISPLAY_OFFSET_X;
|
|
|
|
y = TOP_SKIP - DISP_FRAME - hp48sx_height - 3;
|
|
|
|
surf = SDLCreateSurfFromData(
|
|
|
|
hp48sx_width, hp48sx_height, hp48sx_bits, ARGBColors[ RIGHT ],
|
|
|
|
0 ); // Background transparent: draw only green menu
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = hp48sx_width;
|
|
|
|
srect.h = hp48sx_height;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = y;
|
|
|
|
drect.w = hp48sx_width;
|
|
|
|
drect.h = hp48sx_height;
|
|
|
|
SDL_BlitSurface( surf, &srect, sdlwindow, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = DISPLAY_OFFSET_X + display_width - 1 - science_width;
|
|
|
|
y = TOP_SKIP - DISP_FRAME - science_height - 4;
|
|
|
|
surf = SDLCreateSurfFromData(
|
|
|
|
science_width, science_height, science_bits, ARGBColors[ RIGHT ],
|
|
|
|
0 ); // Background transparent: draw only green menu
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = science_width;
|
|
|
|
srect.h = science_height;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = y;
|
|
|
|
drect.w = science_width;
|
|
|
|
drect.h = science_height;
|
|
|
|
SDL_BlitSurface( surf, &srect, sdlwindow, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
///////////////////////////////////////////////
|
|
|
|
// SDL PORT
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
void SDLCreateColors() {
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
for ( i = WHITE; i < BLACK; i++ )
|
|
|
|
ARGBColors[ i ] = 0xff000000 | ( colors[ i ].r << 16 ) |
|
|
|
|
( colors[ i ].g << 8 ) | colors[ i ].b;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Adjust the LCD color according to the contrast
|
|
|
|
int contrast, r, g, b;
|
|
|
|
contrast = display.contrast;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( contrast < 0x3 )
|
|
|
|
contrast = 0x3;
|
|
|
|
if ( contrast > 0x13 )
|
|
|
|
contrast = 0x13;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
r = ( 0x13 - contrast ) * ( colors[ LCD ].r / 0x10 );
|
|
|
|
g = ( 0x13 - contrast ) * ( colors[ LCD ].g / 0x10 );
|
|
|
|
b = 128 - ( ( 0x13 - contrast ) * ( ( 128 - colors[ LCD ].b ) / 0x10 ) );
|
|
|
|
ARGBColors[ PIXEL ] = 0xff000000 | ( r << 16 ) | ( g << 8 ) | b;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
// SDL PORT
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
void SDLCreateKeys( void ) {
|
|
|
|
unsigned i, x, y;
|
|
|
|
/* SDL_Rect srect, drect; */
|
|
|
|
unsigned pixel;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
2023-05-03 09:40:52 +02:00
|
|
|
// Create surfaces for each button
|
|
|
|
if ( !buttons[ i ].surfaceup ) {
|
|
|
|
buttons[ i ].surfaceup = SDL_CreateRGBSurface(
|
|
|
|
SDL_SWSURFACE, buttons[ i ].w, buttons[ i ].h, 32, 0x00ff0000,
|
|
|
|
0x0000ff00, 0x000000ff, 0xff000000 );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( !buttons[ i ].surfacedown ) {
|
|
|
|
buttons[ i ].surfacedown = SDL_CreateRGBSurface(
|
|
|
|
SDL_SWSURFACE, buttons[ i ].w, buttons[ i ].h, 32, 0x00ff0000,
|
|
|
|
0x0000ff00, 0x000000ff, 0xff000000 );
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
if (i < BUTTON_MTH)
|
|
|
|
pixel = ARGBColors[DISP_PAD];
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (opt_gx && buttons[i].is_menu)
|
|
|
|
pixel = ARGBColors[UNDERLAY];
|
|
|
|
else
|
|
|
|
pixel = ARGBColors[PAD];
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
// Use alpha channel
|
|
|
|
pixel = 0x00000000;
|
|
|
|
// pixel = 0xffff0000;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Fill the button and outline
|
|
|
|
SDL_FillRect( buttons[ i ].surfaceup, 0, pixel );
|
|
|
|
SDL_FillRect( buttons[ i ].surfacedown, 0, pixel );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_Rect rect;
|
|
|
|
rect.x = 1;
|
|
|
|
rect.y = 1;
|
|
|
|
rect.w = buttons[ i ].w - 2;
|
|
|
|
rect.h = buttons[ i ].h - 2;
|
|
|
|
SDL_FillRect( buttons[ i ].surfaceup, &rect, ARGBColors[ BUTTON ] );
|
|
|
|
SDL_FillRect( buttons[ i ].surfacedown, &rect, ARGBColors[ BUTTON ] );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// draw the released button
|
|
|
|
#if defined( GUI_IS_SDL1 )
|
|
|
|
// draw edge of button
|
|
|
|
lineColor( buttons[ i ].surfaceup, 1, buttons[ i ].h - 2, 1, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, 2, buttons[ i ].h - 3, 2, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, 3, buttons[ i ].h - 4, 3, 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( buttons[ i ].surfaceup, 1, 1, buttons[ i ].w - 2, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, 2, 2, buttons[ i ].w - 3, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, 3, 3, buttons[ i ].w - 4, 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, 4, 4, buttons[ i ].w - 5, 4,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
pixelColor( buttons[ i ].surfaceup, 4, 5,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( buttons[ i ].surfaceup, 3, buttons[ i ].h - 2,
|
|
|
|
buttons[ i ].w - 2, buttons[ i ].h - 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, 4, buttons[ i ].h - 3,
|
|
|
|
buttons[ i ].w - 3, buttons[ i ].h - 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( buttons[ i ].surfaceup, buttons[ i ].w - 2,
|
|
|
|
buttons[ i ].h - 2, buttons[ i ].w - 2, 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, buttons[ i ].w - 3,
|
|
|
|
buttons[ i ].h - 3, buttons[ i ].w - 3, 4,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, buttons[ i ].w - 4,
|
|
|
|
buttons[ i ].h - 4, buttons[ i ].w - 4, 5,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfaceup, buttons[ i ].w - 5,
|
|
|
|
buttons[ i ].h - 4, SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// draw frame around button
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( buttons[ i ].surfaceup, 0, buttons[ i ].h - 3, 0, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, 2, 0, buttons[ i ].w - 3, 0,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, 2, buttons[ i ].h - 1,
|
|
|
|
buttons[ i ].w - 3, buttons[ i ].h - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( buttons[ i ].surfaceup, buttons[ i ].w - 1,
|
|
|
|
buttons[ i ].h - 3, buttons[ i ].w - 1, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
if ( i == BUTTON_ON ) {
|
|
|
|
lineColor( buttons[ i ].surfaceup, 1, 1, buttons[ 1 ].w - 2, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfaceup, 1, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfaceup, buttons[ i ].w - 2, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
} else {
|
|
|
|
pixelColor( buttons[ i ].surfaceup, 1, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfaceup, buttons[ i ].w - 2, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
}
|
|
|
|
pixelColor( buttons[ i ].surfaceup, 1, buttons[ i ].h - 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfaceup, buttons[ i ].w - 2,
|
|
|
|
buttons[ i ].h - 2, SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
|
|
|
|
// draw the depressed button
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// draw edge of button
|
|
|
|
lineColor( buttons[ i ].surfacedown, 2, buttons[ i ].h - 4, 2, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, 3, buttons[ i ].h - 5, 3, 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, 2, 2, buttons[ i ].w - 4, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, 3, 3, buttons[ i ].w - 5, 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, 4, 4,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_TOP ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( buttons[ i ].surfacedown, 3, buttons[ i ].h - 3,
|
|
|
|
buttons[ i ].w - 3, buttons[ i ].h - 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, 4, buttons[ i ].h - 4,
|
|
|
|
buttons[ i ].w - 4, buttons[ i ].h - 4,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, buttons[ i ].w - 3,
|
|
|
|
buttons[ i ].h - 3, buttons[ i ].w - 3, 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, buttons[ i ].w - 4,
|
|
|
|
buttons[ i ].h - 4, buttons[ i ].w - 4, 4,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, buttons[ i ].w - 5,
|
|
|
|
buttons[ i ].h - 5, SDLBGRA2ARGB( ARGBColors[ BUT_BOT ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// draw frame around button
|
|
|
|
lineColor( buttons[ i ].surfacedown, 0, buttons[ i ].h - 3, 0, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, 2, 0, buttons[ i ].w - 3, 0,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, 2, buttons[ i ].h - 1,
|
|
|
|
buttons[ i ].w - 3, buttons[ i ].h - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
lineColor( buttons[ i ].surfacedown, buttons[ i ].w - 1,
|
|
|
|
buttons[ i ].h - 3, buttons[ i ].w - 1, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( i == BUTTON_ON ) {
|
|
|
|
lineColor( buttons[ i ].surfacedown, 1, 1, buttons[ i ].w - 2, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, 1, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, buttons[ i ].w - 2, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
} else {
|
|
|
|
pixelColor( buttons[ i ].surfacedown, 1, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, buttons[ i ].w - 2, 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
}
|
|
|
|
pixelColor( buttons[ i ].surfacedown, 1, buttons[ i ].h - 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, buttons[ i ].w - 2,
|
|
|
|
buttons[ i ].h - 2, SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
if ( i == BUTTON_ON ) {
|
|
|
|
rectangleColor( buttons[ i ].surfacedown, 1, 2,
|
|
|
|
1 + buttons[ i ].w - 3, 2 + buttons[ i ].h - 4,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, 2, 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, buttons[ i ].w - 3, 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
} else {
|
|
|
|
rectangleColor( buttons[ i ].surfacedown, 1, 1,
|
|
|
|
1 + buttons[ i ].w - 3, 1 + buttons[ i ].h - 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, 2, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, buttons[ i ].w - 3, 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
}
|
|
|
|
pixelColor( buttons[ i ].surfacedown, 2, buttons[ i ].h - 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
|
|
|
pixelColor( buttons[ i ].surfacedown, buttons[ i ].w - 3,
|
|
|
|
buttons[ i ].h - 3, SDLBGRA2ARGB( ARGBColors[ FRAME ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( buttons[ i ].label != ( char* )0 ) {
|
|
|
|
// Todo: use SDL_ttf to print "nice" fonts
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// for the time being use SDL_gfxPrimitives' font
|
|
|
|
x = ( buttons[ i ].w - strlen( buttons[ i ].label ) * 8 ) / 2;
|
|
|
|
y = ( buttons[ i ].h + 1 ) / 2 - 4;
|
|
|
|
stringColor( buttons[ i ].surfaceup, x, y, buttons[ i ].label,
|
|
|
|
0xffffffff );
|
|
|
|
stringColor( buttons[ i ].surfacedown, x, y, buttons[ i ].label,
|
|
|
|
0xffffffff );
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
// Pixmap centered in button
|
|
|
|
if ( buttons[ i ].lw != 0 ) {
|
|
|
|
// If there's a bitmap, try to plot this
|
|
|
|
unsigned colorbg = ARGBColors[ BUTTON ];
|
|
|
|
unsigned colorfg = ARGBColors[ buttons[ i ].lc ];
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Blit the label surface to the button
|
|
|
|
SDL_Surface* surf;
|
|
|
|
surf = SDLCreateSurfFromData( buttons[ i ].lw, buttons[ i ].lh,
|
|
|
|
buttons[ i ].lb, colorfg, colorbg );
|
|
|
|
// Draw the surface on the center of the button
|
|
|
|
x = ( 1 + buttons[ i ].w - buttons[ i ].lw ) / 2;
|
|
|
|
y = ( 1 + buttons[ i ].h - buttons[ i ].lh ) / 2 + 1;
|
|
|
|
SDL_Rect srect;
|
|
|
|
SDL_Rect drect;
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = buttons[ i ].lw;
|
|
|
|
srect.h = buttons[ i ].lh;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = y;
|
|
|
|
drect.w = buttons[ i ].lw;
|
|
|
|
drect.h = buttons[ i ].lh;
|
|
|
|
SDL_BlitSurface( surf, &srect, buttons[ i ].surfacedown, &drect );
|
|
|
|
SDL_BlitSurface( surf, &srect, buttons[ i ].surfaceup, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Draw the left labels (violet on GX)
|
|
|
|
void SDLDrawKeyLabelLeft() {
|
|
|
|
int i, x, y;
|
|
|
|
unsigned int pw /* , ph */;
|
|
|
|
int wl, wr, ws;
|
|
|
|
int offset_y = KEYBOARD_OFFSET_Y;
|
|
|
|
int offset_x = KEYBOARD_OFFSET_X;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
unsigned colorbg, colorfg;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Draw the left labels
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
|
|
|
// No label -> skip
|
|
|
|
if ( buttons[ i ].left == ( char* )0 )
|
|
|
|
continue;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( buttons[ i ].is_menu ) {
|
|
|
|
// draw the dark shade under the label
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( opt_gx ) {
|
|
|
|
pw = 58;
|
|
|
|
/* ph = 48; */
|
|
|
|
} else {
|
|
|
|
pw = 46;
|
|
|
|
/* ph = 11; */
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// pix = XCreatePixmap(dpy, keypad->pixmap, pw, ph, depth);
|
|
|
|
// XSetForeground(dpy, gc, COLOR(UNDERLAY));
|
|
|
|
// XFillRectangle(dpy, pix, gc, 0, 0, pw, ph);
|
|
|
|
// XSetBackground(dpy, gc, COLOR(UNDERLAY));
|
|
|
|
// XSetForeground(dpy, gc, COLOR(LEFT));
|
|
|
|
colorbg = ARGBColors[ UNDERLAY ];
|
|
|
|
colorfg = ARGBColors[ LEFT ];
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = ( pw + 1 -
|
|
|
|
SmallTextWidth( buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) ) ) /
|
|
|
|
2;
|
|
|
|
if ( opt_gx )
|
|
|
|
y = 14;
|
|
|
|
else
|
|
|
|
y = 9;
|
|
|
|
|
|
|
|
if ( !opt_gx ) {
|
|
|
|
// Removed some sx draw code
|
|
|
|
// XDrawPoint(dpy, pix, gc, 0, 0);
|
|
|
|
// XDrawPoint(dpy, pix, gc, 0, ph - 1);
|
|
|
|
// XDrawPoint(dpy, pix, gc, pw - 1, 0);
|
|
|
|
// XDrawPoint(dpy, pix, gc, pw - 1, ph - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the coordinates to absolute
|
|
|
|
if ( opt_gx ) {
|
|
|
|
x += offset_x + buttons[ i ].x - 6;
|
|
|
|
y += offset_y + buttons[ i ].y - small_ascent - small_descent -
|
|
|
|
6;
|
|
|
|
} else {
|
|
|
|
x += offset_x + buttons[ i ].x + ( buttons[ i ].w - pw ) / 2;
|
|
|
|
y += offset_y + buttons[ i ].y - small_ascent - small_descent;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLDrawSmallString( x, y, buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ), colorfg, colorbg );
|
|
|
|
} else // is_menu
|
|
|
|
{
|
|
|
|
colorbg = ARGBColors[ BLACK ];
|
|
|
|
colorfg = ARGBColors[ LEFT ];
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( buttons[ i ].right == ( char* )0 ) {
|
|
|
|
// centered label
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w -
|
|
|
|
SmallTextWidth( buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) ) ) /
|
|
|
|
2;
|
|
|
|
} else {
|
|
|
|
// label to the left
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
wl = SmallTextWidth( buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) );
|
|
|
|
wr = SmallTextWidth( buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) );
|
|
|
|
ws = SmallTextWidth( " ", 1 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w - ( wl + wr + ws ) ) / 2;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
y = offset_y + buttons[ i ].y - small_descent;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLDrawSmallString( x, y, buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ), colorfg, colorbg );
|
|
|
|
} // is_menu
|
|
|
|
|
|
|
|
} // for
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Draw the right labels (green on GX)
|
|
|
|
void SDLDrawKeyLabelRight() {
|
|
|
|
int i, x, y;
|
|
|
|
unsigned int pw /* , ph */;
|
|
|
|
int wl, wr, ws;
|
|
|
|
int offset_y = KEYBOARD_OFFSET_Y;
|
|
|
|
int offset_x = KEYBOARD_OFFSET_X;
|
|
|
|
unsigned colorbg, colorfg;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// draw the right labels
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// if (i < BUTTON_MTH)
|
|
|
|
// pixel = COLOR(DISP_PAD);
|
|
|
|
// else
|
|
|
|
// pixel = COLOR(PAD);
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( buttons[ i ].right == ( char* )0 )
|
|
|
|
continue;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( buttons[ i ].is_menu ) {
|
|
|
|
// draw the dark shade under the label
|
|
|
|
if ( opt_gx ) {
|
|
|
|
pw = 58;
|
|
|
|
/* ph = 48; */
|
|
|
|
} else {
|
|
|
|
pw = 44;
|
|
|
|
/* ph = 9; */
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
colorbg = ARGBColors[ UNDERLAY ];
|
|
|
|
colorfg = ARGBColors[ RIGHT ];
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = ( pw + 1 -
|
|
|
|
SmallTextWidth( buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) ) ) /
|
|
|
|
2;
|
|
|
|
if ( opt_gx )
|
|
|
|
y = 14;
|
|
|
|
else
|
|
|
|
y = 8;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( !opt_gx ) {
|
|
|
|
// Removed some sx draw code
|
|
|
|
// XDrawPoint(dpy, pix, gc, 0, 0);
|
|
|
|
// XDrawPoint(dpy, pix, gc, 0, ph - 1);
|
|
|
|
// XDrawPoint(dpy, pix, gc, pw - 1, 0);
|
|
|
|
// XDrawPoint(dpy, pix, gc, pw - 1, ph - 1);
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Set the coordinates to absolute
|
|
|
|
if ( opt_gx ) {
|
|
|
|
x += offset_x + buttons[ i ].x - 6;
|
|
|
|
y += offset_y + buttons[ i ].y - small_ascent - small_descent -
|
|
|
|
6;
|
|
|
|
} else {
|
|
|
|
x += offset_x + buttons[ i ].x + ( buttons[ i ].w - pw ) / 2;
|
|
|
|
y += offset_y + buttons[ i ].y - small_ascent - small_descent;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLDrawSmallString( x, y, buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ), colorfg,
|
|
|
|
colorbg );
|
|
|
|
} // buttons[i].is_menu
|
|
|
|
else {
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// XSetBackground(dpy, gc, pixel);
|
|
|
|
// XSetForeground(dpy, gc, COLOR(RIGHT));
|
|
|
|
colorbg = ARGBColors[ BLACK ];
|
|
|
|
colorfg = ARGBColors[ RIGHT ];
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( buttons[ i ].left == ( char* )0 ) {
|
|
|
|
// centered label
|
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w -
|
|
|
|
SmallTextWidth( buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) ) ) /
|
|
|
|
2;
|
|
|
|
} else {
|
|
|
|
// label to the right
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
wl = SmallTextWidth( buttons[ i ].left,
|
|
|
|
strlen( buttons[ i ].left ) );
|
|
|
|
wr = SmallTextWidth( buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ) );
|
|
|
|
ws = SmallTextWidth( " ", 1 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w - ( wl + wr + ws ) ) / 2 + wl + ws;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
y = offset_y + buttons[ i ].y - small_descent;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// DrawSmallString(dpy, keypad->pixmap, gc, x, y,
|
|
|
|
// buttons[i].right, strlen(buttons[i].right));
|
|
|
|
SDLDrawSmallString( x, y, buttons[ i ].right,
|
|
|
|
strlen( buttons[ i ].right ), colorfg,
|
|
|
|
colorbg );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
} // for
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Draw the letter bottom right of the key
|
|
|
|
void SDLDrawKeyLetter() {
|
|
|
|
int i, x, y;
|
|
|
|
int offset_y = KEYBOARD_OFFSET_Y;
|
|
|
|
int offset_x = KEYBOARD_OFFSET_X;
|
|
|
|
unsigned colorbg;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( i < BUTTON_MTH )
|
|
|
|
colorbg = ARGBColors[ DISP_PAD ];
|
|
|
|
else
|
|
|
|
colorbg = ARGBColors[ PAD ];
|
|
|
|
|
|
|
|
// Letter ( small character bottom right of key)
|
|
|
|
if ( buttons[ i ].letter != ( char* )0 ) {
|
|
|
|
if ( opt_gx ) {
|
|
|
|
x = offset_x + buttons[ i ].x + buttons[ i ].w + 3;
|
|
|
|
y = offset_y + buttons[ i ].y + buttons[ i ].h + 1;
|
|
|
|
} else {
|
|
|
|
x = offset_x + buttons[ i ].x + buttons[ i ].w -
|
|
|
|
SmallTextWidth( buttons[ i ].letter, 1 ) / 2 + 5;
|
|
|
|
y = offset_y + buttons[ i ].y + buttons[ i ].h - 2;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLDrawSmallString( x, y, buttons[ i ].letter, 1, 0xffffffff,
|
|
|
|
colorbg );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Bottom label: the only one is the cancel button
|
|
|
|
void SDLDrawKeyLabelBottom() {
|
|
|
|
int i, x, y;
|
|
|
|
int offset_y = KEYBOARD_OFFSET_Y;
|
|
|
|
int offset_x = KEYBOARD_OFFSET_X;
|
|
|
|
unsigned colorbg, colorfg;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Bottom label: the only one is the cancel button
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
|
|
|
if ( buttons[ i ].sub == ( char* )0 )
|
|
|
|
continue;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( i < BUTTON_MTH )
|
|
|
|
colorbg = ARGBColors[ DISP_PAD ];
|
|
|
|
else
|
|
|
|
colorbg = ARGBColors[ PAD ];
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
colorfg = ARGBColors[ WHITE ];
|
|
|
|
|
|
|
|
x = offset_x + buttons[ i ].x +
|
|
|
|
( 1 + buttons[ i ].w -
|
|
|
|
SmallTextWidth( buttons[ i ].sub, strlen( buttons[ i ].sub ) ) ) /
|
|
|
|
2;
|
|
|
|
y = offset_y + buttons[ i ].y + buttons[ i ].h + small_ascent + 2;
|
|
|
|
SDLDrawSmallString( x, y, buttons[ i ].sub, strlen( buttons[ i ].sub ),
|
|
|
|
colorfg, colorbg );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Draws the greyish area around keys that trigger menus
|
|
|
|
void SDLDrawKeyMenu() {
|
|
|
|
int i, x, y;
|
|
|
|
int offset_y = KEYBOARD_OFFSET_Y;
|
|
|
|
int offset_x = KEYBOARD_OFFSET_X;
|
|
|
|
SDL_Rect rect;
|
|
|
|
unsigned color;
|
|
|
|
unsigned pw, ph;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
|
|
|
if ( !buttons[ i ].is_menu )
|
|
|
|
continue;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// draw the dark shade under the label
|
|
|
|
if ( opt_gx ) {
|
|
|
|
pw = 58;
|
|
|
|
ph = 48;
|
|
|
|
} else {
|
|
|
|
pw = 44;
|
|
|
|
ph = 9;
|
|
|
|
}
|
|
|
|
color = ARGBColors[ UNDERLAY ];
|
|
|
|
|
|
|
|
// Set the coordinates to absolute
|
|
|
|
if ( opt_gx ) {
|
|
|
|
x = offset_x + buttons[ i ].x - 6;
|
|
|
|
y = offset_y + buttons[ i ].y - small_ascent - small_descent - 6;
|
|
|
|
} else {
|
|
|
|
x = offset_x + buttons[ i ].x + ( buttons[ i ].w - pw ) / 2;
|
|
|
|
y = offset_y + buttons[ i ].y - small_ascent - small_descent;
|
|
|
|
}
|
|
|
|
|
|
|
|
rect.x = x;
|
|
|
|
rect.y = y;
|
|
|
|
rect.w = pw;
|
|
|
|
rect.h = ph;
|
|
|
|
SDL_FillRect( sdlwindow, &rect, color );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLDrawButtons() {
|
|
|
|
int i;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
|
|
|
SDL_Rect /* rect, */ srect, drect;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Blit the button surface to the screen
|
2023-04-30 16:34:53 +02:00
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
2023-05-03 09:40:52 +02:00
|
|
|
srect.w = buttons[ i ].w;
|
|
|
|
srect.h = buttons[ i ].h;
|
|
|
|
drect.x = KEYBOARD_OFFSET_X + buttons[ i ].x;
|
|
|
|
drect.y = KEYBOARD_OFFSET_Y + buttons[ i ].y;
|
|
|
|
drect.w = buttons[ i ].w;
|
|
|
|
drect.h = buttons[ i ].h;
|
|
|
|
if ( buttons[ i ].pressed ) {
|
|
|
|
SDL_BlitSurface( buttons[ i ].surfacedown, &srect, sdlwindow,
|
|
|
|
&drect );
|
|
|
|
} else {
|
|
|
|
SDL_BlitSurface( buttons[ i ].surfaceup, &srect, sdlwindow,
|
|
|
|
&drect );
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Always update immediately buttons
|
|
|
|
SDL_UpdateRect(
|
|
|
|
sdlwindow, KEYBOARD_OFFSET_X + buttons[ 0 ].x,
|
|
|
|
KEYBOARD_OFFSET_Y + buttons[ 0 ].y,
|
|
|
|
buttons[ LAST_BUTTON ].x + buttons[ LAST_BUTTON ].w - buttons[ 0 ].x,
|
|
|
|
buttons[ LAST_BUTTON ].y + buttons[ LAST_BUTTON ].h - buttons[ 0 ].y );
|
|
|
|
}
|
|
|
|
void SDLDrawKeypad( void ) {
|
|
|
|
/* int i, x, y; */
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLDrawKeyMenu();
|
|
|
|
SDLDrawKeyLetter();
|
|
|
|
SDLDrawKeyLabelBottom();
|
|
|
|
SDLDrawKeyLabelLeft();
|
|
|
|
SDLDrawKeyLabelRight();
|
|
|
|
SDLCreateKeys();
|
|
|
|
SDLDrawButtons();
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLDrawSmallString( int x, int y, const char* string, unsigned int length,
|
|
|
|
unsigned int coloron, unsigned int coloroff ) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
// printf("draw string: %d, %d, %s\n",x,y,string);
|
|
|
|
for ( i = 0; i < length; i++ ) {
|
|
|
|
if ( small_font[ ( int )string[ i ] ].h != 0 ) {
|
|
|
|
int w = small_font[ ( int )string[ i ] ].w;
|
|
|
|
int h = small_font[ ( int )string[ i ] ].h;
|
|
|
|
|
|
|
|
SDL_Surface* surf = SDLCreateSurfFromData(
|
|
|
|
w, h, small_font[ ( int )string[ i ] ].bits, coloron,
|
|
|
|
coloroff );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_Rect srect;
|
|
|
|
SDL_Rect drect;
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = w;
|
|
|
|
srect.h = h;
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = ( int )( y - small_font[ ( int )string[ i ] ].h );
|
|
|
|
drect.w = w;
|
|
|
|
drect.h = h;
|
|
|
|
SDL_BlitSurface( surf, &srect, sdlwindow, &drect );
|
|
|
|
SDL_FreeSurface( surf );
|
|
|
|
}
|
|
|
|
x += SmallTextWidth( &string[ i ], 1 );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLDrawBezel( unsigned int width, unsigned int height,
|
|
|
|
unsigned int offset_y, unsigned int offset_x ) {
|
|
|
|
int i /* , x, y*/;
|
|
|
|
int display_height = DISPLAY_HEIGHT;
|
|
|
|
int display_width = DISPLAY_WIDTH;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// draw the frame around the display
|
|
|
|
for ( i = 0; i < DISP_FRAME; i++ ) {
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - i,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * i,
|
|
|
|
DISPLAY_OFFSET_X + display_width + i,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * i,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - i,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * i + 1,
|
|
|
|
DISPLAY_OFFSET_X + display_width + i,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * i + 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_TOP ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X + display_width + i,
|
|
|
|
DISPLAY_OFFSET_Y - i, DISPLAY_OFFSET_X + display_width + i,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * i,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_TOP ] ) );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for ( i = 0; i < DISP_FRAME; i++ ) {
|
|
|
|
lineColor(
|
|
|
|
sdlwindow, DISPLAY_OFFSET_X - i - 1, DISPLAY_OFFSET_Y - i - 1,
|
|
|
|
DISPLAY_OFFSET_X + display_width + i - 1, DISPLAY_OFFSET_Y - i - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - i - 1,
|
|
|
|
DISPLAY_OFFSET_Y - i - 1, DISPLAY_OFFSET_X - i - 1,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * i - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD_BOT ] ) );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// round off corners
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - DISP_FRAME,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME, DISPLAY_OFFSET_X - DISP_FRAME + 3,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - DISP_FRAME,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME, DISPLAY_OFFSET_X - DISP_FRAME,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME + 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
pixelColor( sdlwindow, DISPLAY_OFFSET_X - DISP_FRAME + 1,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME + 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X + display_width + DISP_FRAME - 4,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME,
|
|
|
|
DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME,
|
|
|
|
DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME + 3,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
pixelColor( sdlwindow, DISPLAY_OFFSET_X + display_width + DISP_FRAME - 2,
|
|
|
|
DISPLAY_OFFSET_Y - DISP_FRAME + 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - DISP_FRAME,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 4,
|
|
|
|
DISPLAY_OFFSET_X - DISP_FRAME,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - DISP_FRAME,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1,
|
|
|
|
DISPLAY_OFFSET_X - DISP_FRAME + 3,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
pixelColor( sdlwindow, DISPLAY_OFFSET_X - DISP_FRAME + 1,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 4,
|
|
|
|
DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X + display_width + DISP_FRAME - 4,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1,
|
|
|
|
DISPLAY_OFFSET_X + display_width + DISP_FRAME - 1,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
pixelColor( sdlwindow, DISPLAY_OFFSET_X + display_width + DISP_FRAME - 2,
|
|
|
|
DISPLAY_OFFSET_Y + display_height + 2 * DISP_FRAME - 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ DISP_PAD ] ) );
|
|
|
|
|
|
|
|
// simulate rounded lcd corners
|
|
|
|
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X - 1, DISPLAY_OFFSET_Y + 1,
|
|
|
|
DISPLAY_OFFSET_X - 1, DISPLAY_OFFSET_Y + display_height - 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ LCD ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X + 1, DISPLAY_OFFSET_Y - 1,
|
|
|
|
DISPLAY_OFFSET_X + display_width - 2, DISPLAY_OFFSET_Y - 1,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ LCD ] ) );
|
|
|
|
lineColor(
|
|
|
|
sdlwindow, DISPLAY_OFFSET_X + 1, DISPLAY_OFFSET_Y + display_height,
|
|
|
|
DISPLAY_OFFSET_X + display_width - 2, DISPLAY_OFFSET_Y + display_height,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ LCD ] ) );
|
|
|
|
lineColor( sdlwindow, DISPLAY_OFFSET_X + display_width,
|
|
|
|
DISPLAY_OFFSET_Y + 1, DISPLAY_OFFSET_X + display_width,
|
|
|
|
DISPLAY_OFFSET_Y + display_height - 2,
|
|
|
|
SDLBGRA2ARGB( ARGBColors[ LCD ] ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLDrawBackground( int width, int height, int w_top, int h_top ) {
|
|
|
|
SDL_Rect rect;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
rect.x = 0;
|
|
|
|
rect.y = 0;
|
|
|
|
rect.w = w_top;
|
|
|
|
rect.h = h_top;
|
|
|
|
SDL_FillRect( sdlwindow, &rect, ARGBColors[ PAD ] );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
rect.w = width;
|
|
|
|
rect.h = height;
|
|
|
|
SDL_FillRect( sdlwindow, &rect, ARGBColors[ DISP_PAD ] );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// LCD
|
|
|
|
rect.x = DISPLAY_OFFSET_X;
|
|
|
|
rect.y = DISPLAY_OFFSET_Y;
|
|
|
|
rect.w = DISPLAY_WIDTH;
|
|
|
|
rect.h = DISPLAY_HEIGHT;
|
|
|
|
SDL_FillRect( sdlwindow, &rect, ARGBColors[ LCD ] );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// SDL stuff
|
|
|
|
SDL_Surface* sdlwindow;
|
|
|
|
SDL_Surface* sdlsurface;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
/* SDL_TimerCallback */
|
|
|
|
/* SDLTimerCallback () */
|
|
|
|
/* { */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
InitSDL InitSDL InitSDL InitSDL InitSDL InitSDL InitSDL
|
|
|
|
*******************************************************************************
|
|
|
|
Basic SDL Initialization and atexit assignment.
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
void SDLInit() {
|
|
|
|
SDL_version compiled;
|
|
|
|
|
|
|
|
// Initialize SDL
|
|
|
|
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
|
|
|
|
printf( "Couldn't initialize SDL: %s\n", SDL_GetError() );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
|
|
|
SDL_VERSION( &compiled );
|
|
|
|
printf( "Compiled version: %d.%d.%d\n", compiled.major, compiled.minor,
|
|
|
|
compiled.patch );
|
|
|
|
printf( "Linked version: %d.%d.%d\n", SDL_Linked_Version()->major,
|
|
|
|
SDL_Linked_Version()->minor, SDL_Linked_Version()->patch );
|
|
|
|
// On exit: clean SDL
|
|
|
|
atexit( SDL_Quit );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// icon
|
|
|
|
/*SDL_Surface *icon;
|
|
|
|
icon =
|
|
|
|
SDLCreateARGBSurfFromData(sdlicon_width,sdlicon_height,sdlicon_bits,SDLToARGB(255,sdlicon_bits[0],sdlicon_bits[1],sdlicon_bits[2]));
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_WM_SetIcon(icon, 0);
|
|
|
|
SDL_FreeSurface(icon);
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
*/
|
|
|
|
/* SDL_WM_SetCaption( "x48ng: HP48 emulator", "x48ng" ); */
|
|
|
|
// Initialize the geometric values
|
|
|
|
KEYBOARD_HEIGHT = _KEYBOARD_HEIGHT;
|
|
|
|
KEYBOARD_WIDTH = _KEYBOARD_WIDTH;
|
|
|
|
TOP_SKIP = _TOP_SKIP;
|
|
|
|
SIDE_SKIP = _SIDE_SKIP;
|
|
|
|
BOTTOM_SKIP = _BOTTOM_SKIP;
|
|
|
|
DISP_KBD_SKIP = _DISP_KBD_SKIP;
|
|
|
|
DISPLAY_WIDTH = _DISPLAY_WIDTH;
|
|
|
|
DISPLAY_HEIGHT = _DISPLAY_HEIGHT;
|
|
|
|
DISPLAY_OFFSET_X = _DISPLAY_OFFSET_X;
|
|
|
|
DISPLAY_OFFSET_Y = _DISPLAY_OFFSET_Y;
|
|
|
|
DISP_FRAME = _DISP_FRAME;
|
|
|
|
KEYBOARD_OFFSET_X = _KEYBOARD_OFFSET_X;
|
|
|
|
KEYBOARD_OFFSET_Y = _KEYBOARD_OFFSET_Y;
|
|
|
|
KBD_UPLINE = _KBD_UPLINE;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
unsigned width =
|
|
|
|
( buttons_gx[ LAST_BUTTON ].x + buttons_gx[ LAST_BUTTON ].w ) +
|
|
|
|
2 * SIDE_SKIP;
|
|
|
|
unsigned height = DISPLAY_OFFSET_Y + DISPLAY_HEIGHT + DISP_KBD_SKIP +
|
|
|
|
buttons_gx[ LAST_BUTTON ].y +
|
|
|
|
buttons_gx[ LAST_BUTTON ].h + BOTTOM_SKIP;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// unsigned width = (buttons_sx[LAST_BUTTON].x +
|
|
|
|
// buttons_sx[LAST_BUTTON].w)
|
|
|
|
// + 2 * SIDE_SKIP; unsigned height = DISPLAY_OFFSET_Y + DISPLAY_HEIGHT
|
|
|
|
// + DISP_KBD_SKIP + buttons_sx[LAST_BUTTON].y +
|
|
|
|
// buttons_sx[LAST_BUTTON].h + BOTTOM_SKIP;
|
|
|
|
printf( "w/h: %d %d\n", width, height );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
sdlwindow = SDL_SetVideoMode( width, height, 32, SDL_SWSURFACE );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( sdlwindow == NULL ) {
|
|
|
|
printf( "Couldn't set video mode: %s\n", SDL_GetError() );
|
|
|
|
exit( 1 );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
/*sdlsurface =
|
|
|
|
SDL_CreateRGBSurface(SDL_SWSURFACE,360,800,32,0x000000ff,0x0000ff00,0x00ff0000,0xff000000);
|
|
|
|
if(sdlsurface==NULL)
|
|
|
|
{
|
|
|
|
printf("Can't create another surface\n");
|
|
|
|
exit(1);
|
|
|
|
}*/
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// SDL_SetTimer(100, SDLTimerCallback);
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// This should be called once to setup the surfaces. Calling it multiple
|
|
|
|
// times is fine, it won't do anything on subsequent calls.
|
|
|
|
void SDLCreateAnnunc() {
|
|
|
|
int i;
|
|
|
|
/* int x, y, idx; */
|
|
|
|
for ( i = 0; i < 6; i++ ) {
|
|
|
|
|
|
|
|
// If the SDL surface does not exist yet, we create it on the fly
|
|
|
|
if ( ann_tbl[ i ].surfaceon ) {
|
|
|
|
SDL_FreeSurface( ann_tbl[ i ].surfaceon );
|
|
|
|
ann_tbl[ i ].surfaceon = 0;
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
ann_tbl[ i ].surfaceon = SDLCreateSurfFromData(
|
|
|
|
ann_tbl[ i ].width, ann_tbl[ i ].height, ann_tbl[ i ].bits,
|
|
|
|
ARGBColors[ PIXEL ], ARGBColors[ LCD ] );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( ann_tbl[ i ].surfaceoff ) {
|
|
|
|
SDL_FreeSurface( ann_tbl[ i ].surfaceoff );
|
|
|
|
ann_tbl[ i ].surfaceoff = 0;
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
ann_tbl[ i ].surfaceoff = SDLCreateSurfFromData(
|
|
|
|
ann_tbl[ i ].width, ann_tbl[ i ].height, ann_tbl[ i ].bits,
|
|
|
|
ARGBColors[ LCD ], ARGBColors[ LCD ] );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLDrawAnnunc( char* annunc ) {
|
|
|
|
int i;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLCreateAnnunc();
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Print the annunciator
|
|
|
|
for ( i = 0; i < 6; i++ ) {
|
|
|
|
SDL_Rect srect;
|
|
|
|
SDL_Rect drect;
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = ann_tbl[ i ].width;
|
|
|
|
srect.h = ann_tbl[ i ].height;
|
|
|
|
drect.x = DISPLAY_OFFSET_X + ann_tbl[ i ].x;
|
|
|
|
drect.y = DISPLAY_OFFSET_Y + ann_tbl[ i ].y;
|
|
|
|
drect.w = ann_tbl[ i ].width;
|
|
|
|
drect.h = ann_tbl[ i ].height;
|
|
|
|
if ( annunc[ i ] )
|
|
|
|
SDL_BlitSurface( ann_tbl[ i ].surfaceon, &srect, sdlwindow,
|
|
|
|
&drect );
|
|
|
|
else
|
|
|
|
SDL_BlitSurface( ann_tbl[ i ].surfaceoff, &srect, sdlwindow,
|
|
|
|
&drect );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Always immediately update annunciators
|
|
|
|
SDL_UpdateRect( sdlwindow, DISPLAY_OFFSET_X + ann_tbl[ 0 ].x,
|
|
|
|
DISPLAY_OFFSET_Y + ann_tbl[ 0 ].y,
|
|
|
|
ann_tbl[ 5 ].x + ann_tbl[ 5 ].width - ann_tbl[ 0 ].x,
|
|
|
|
ann_tbl[ 5 ].y + ann_tbl[ 5 ].height - ann_tbl[ 0 ].y );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// lcd_buffer contains one nibble per byte (4 useful bit of data per byte)
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// void SDLDrawLcd(unsigned char lcd_buffer[DISP_ROWS][NIBS_PER_BUFFER_ROW])
|
|
|
|
/*void SDLDrawLcd()
|
|
|
|
{
|
|
|
|
// Do something here
|
|
|
|
int x,y;
|
|
|
|
int xoffset = DISPLAY_OFFSET_X+5;
|
|
|
|
int yoffset = DISPLAY_OFFSET_Y+20;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_LockSurface(sdlwindow);
|
|
|
|
unsigned char *buffer=sdlwindow->pixels;
|
|
|
|
unsigned int pitch = sdlwindow->pitch;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
unsigned char c = lcd_buffer[0][0];
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for(y=0;y<2*DISP_ROWS;y++)
|
|
|
|
{
|
|
|
|
unsigned int *lineptr;
|
|
|
|
lineptr = (unsigned int*)(buffer + pitch*(yoffset + y));
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for(x=0;x<131;x++)
|
|
|
|
{
|
|
|
|
// Check if bit is on
|
|
|
|
char c = lcd_buffer[y/2][x>>2]; // The 4
|
|
|
|
lower bits in a byte are used (1 nibble per byte) char b = c & (1<<(x&3));
|
|
|
|
if(b)
|
|
|
|
{
|
|
|
|
lineptr[xoffset+2*x]=ARGBColors[PIXEL];
|
|
|
|
lineptr[xoffset+2*x+1]=ARGBColors[PIXEL];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lineptr[xoffset+2*x]=ARGBColors[LCD];
|
|
|
|
lineptr[xoffset+2*x+1]=ARGBColors[LCD];
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
SDL_UnlockSurface(sdlwindow);
|
|
|
|
SDL_UpdateRect(sdlwindow, 0,0,0,0); // Should optimize:
|
|
|
|
only update the area of the icons
|
|
|
|
}*/
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLDrawNibble( int _x, int _y, int val ) {
|
|
|
|
int x, y;
|
|
|
|
int xoffset = DISPLAY_OFFSET_X + 5;
|
|
|
|
int yoffset = DISPLAY_OFFSET_Y + 20;
|
|
|
|
/* static unsigned ctr = 0; */
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_LockSurface( sdlwindow );
|
|
|
|
unsigned char* buffer = ( unsigned char* )sdlwindow->pixels;
|
|
|
|
unsigned int pitch = sdlwindow->pitch;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for ( y = 0; y < 2; y++ ) {
|
|
|
|
unsigned int* lineptr;
|
|
|
|
lineptr =
|
|
|
|
( unsigned int* )( buffer + pitch * ( yoffset + 2 * _y + y ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
for ( x = 0; x < 4; x++ ) {
|
|
|
|
// Check if bit is on
|
|
|
|
// char c = lcd_buffer[y/2][x>>2]; // The 4 lower bits
|
|
|
|
// in a byte are used (1 nibble per byte)
|
|
|
|
if ( _x + x >= 131 ) // Clip at 131 pixels (some nibble writes may
|
|
|
|
// go beyond the range, but are not visible)
|
|
|
|
break;
|
|
|
|
char c = val;
|
|
|
|
char b = c & ( 1 << ( x & 3 ) );
|
|
|
|
if ( b ) {
|
|
|
|
lineptr[ xoffset + 2 * ( _x + x ) ] = ARGBColors[ PIXEL ];
|
|
|
|
lineptr[ xoffset + 2 * ( _x + x ) + 1 ] = ARGBColors[ PIXEL ];
|
2023-04-30 16:34:53 +02:00
|
|
|
} else {
|
2023-05-03 09:40:52 +02:00
|
|
|
lineptr[ xoffset + 2 * ( _x + x ) ] = ARGBColors[ LCD ];
|
|
|
|
lineptr[ xoffset + 2 * ( _x + x ) + 1 ] = ARGBColors[ LCD ];
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
SDL_UnlockSurface( sdlwindow );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
#ifndef DELAYEDDISPUPDATE
|
|
|
|
// Either update immediately or with a delay the display
|
|
|
|
SDL_UpdateRect( sdlwindow, xoffset + 2 * _x, yoffset + 2 * _y, 8, 2 );
|
|
|
|
#endif
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
/*
|
|
|
|
Create a surface from binary bitmap data
|
|
|
|
*/
|
|
|
|
SDL_Surface* SDLCreateSurfFromData( unsigned int w, unsigned int h,
|
|
|
|
unsigned char* data, unsigned int coloron,
|
|
|
|
unsigned int coloroff ) {
|
|
|
|
int x, y;
|
|
|
|
SDL_Surface* surf;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
surf = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, 0x00ff0000,
|
|
|
|
0x0000ff00, 0x000000ff, 0xff000000 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_LockSurface( surf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
unsigned char* pixels = ( unsigned char* )surf->pixels;
|
|
|
|
unsigned int pitch = surf->pitch;
|
|
|
|
unsigned byteperline = w / 8;
|
|
|
|
if ( byteperline * 8 != w )
|
|
|
|
byteperline++;
|
|
|
|
for ( y = 0; y < h; y++ ) {
|
|
|
|
unsigned int* lineptr = ( unsigned int* )( pixels + y * pitch );
|
|
|
|
for ( x = 0; x < w; x++ ) {
|
|
|
|
// Address the correct byte
|
|
|
|
char c = data[ y * byteperline + ( x >> 3 ) ];
|
|
|
|
// Look for the bit in that byte
|
|
|
|
char b = c & ( 1 << ( x & 7 ) );
|
|
|
|
if ( b )
|
|
|
|
lineptr[ x ] = coloron;
|
|
|
|
else
|
|
|
|
lineptr[ x ] = coloroff;
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_UnlockSurface( surf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
return surf;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Create a ARGB surface from RGB data. Allows to set a transparent color
|
|
|
|
SDL_Surface* SDLCreateARGBSurfFromData( unsigned int w, unsigned int h,
|
|
|
|
unsigned char* data,
|
|
|
|
unsigned int xpcolor ) {
|
|
|
|
int x, y;
|
|
|
|
SDL_Surface* surf;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
surf = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, 0x00ff0000,
|
|
|
|
0x0000ff00, 0x000000ff, 0xff000000 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_LockSurface( surf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
unsigned char* pixels = ( unsigned char* )surf->pixels;
|
|
|
|
unsigned int pitch = surf->pitch;
|
|
|
|
for ( y = 0; y < h; y++ ) {
|
|
|
|
unsigned int* lineptr = ( unsigned int* )( pixels + y * pitch );
|
|
|
|
for ( x = 0; x < w; x++ ) {
|
|
|
|
unsigned r, g, b, color;
|
|
|
|
r = data[ y * w * 3 + x * 3 ];
|
|
|
|
g = data[ y * w * 3 + x * 3 + 1 ];
|
|
|
|
b = data[ y * w * 3 + x * 3 + 2 ];
|
|
|
|
color = SDLToARGB( 255, r, g, b );
|
|
|
|
|
|
|
|
// Set alpha to 0 for transparent colors
|
|
|
|
if ( ( color & 0xffffff ) == ( xpcolor & 0xffffff ) ) {
|
|
|
|
color = color & 0xffffff;
|
|
|
|
}
|
|
|
|
lineptr[ x ] = color;
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
}
|
|
|
|
SDL_UnlockSurface( surf );
|
|
|
|
return surf;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
unsigned SDLBGRA2ARGB( unsigned color ) {
|
|
|
|
unsigned a, r, g, b;
|
|
|
|
SDLARGBTo( color, &a, &r, &g, &b );
|
|
|
|
|
|
|
|
// color = a | (b<<24) | (g<<16) | (r<<8);
|
|
|
|
color = a | ( r << 24 ) | ( g << 16 ) | ( b << 8 );
|
|
|
|
return color;
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// State to displayed zoomed last pressed key
|
|
|
|
SDL_Surface* showkeylastsurf = 0;
|
|
|
|
int showkeylastx, showkeylasty, showkeylastkey;
|
|
|
|
// Show the hp key which is being pressed
|
|
|
|
void SDLUIShowKey( int hpkey ) {
|
|
|
|
SDL_Rect /* rect, */ srect, drect;
|
|
|
|
SDL_Surface *ssurf, *zsurf;
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
// double zoomfactor = 1.5;
|
|
|
|
double zoomfactor = 3;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// If we're called with the same key as before, do nothing
|
|
|
|
if ( showkeylastkey == hpkey )
|
|
|
|
return;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
showkeylastkey = hpkey;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Starts by hiding last
|
|
|
|
SDLUIHideKey();
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( hpkey == -1 )
|
|
|
|
return;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Which surface to show
|
|
|
|
if ( buttons[ hpkey ].pressed )
|
|
|
|
ssurf = buttons[ hpkey ].surfacedown;
|
|
|
|
else
|
|
|
|
ssurf = buttons[ hpkey ].surfaceup;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Zoomed surface
|
|
|
|
// zsurf = zoomSurface(ssurf,1.5,1.9,1);
|
|
|
|
/* unsigned t1, t2; */
|
|
|
|
/* t1 = SDL_GetTicks (); */
|
|
|
|
zsurf = zoomSurface( ssurf, zoomfactor, zoomfactor, 0 );
|
|
|
|
/* t2 = SDL_GetTicks (); */
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Background backup
|
|
|
|
showkeylastsurf =
|
|
|
|
SDL_CreateRGBSurface( SDL_SWSURFACE, zsurf->w, zsurf->h, 32, 0x00ff0000,
|
|
|
|
0x0000ff00, 0x000000ff, 0xff000000 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Where to
|
|
|
|
x = KEYBOARD_OFFSET_X + buttons[ hpkey ].x -
|
|
|
|
( zsurf->w - ssurf->w + 1 ) / 2;
|
|
|
|
y = KEYBOARD_OFFSET_Y + buttons[ hpkey ].y -
|
|
|
|
( zsurf->h - ssurf->h + 1 ) / 2;
|
|
|
|
// blitting does not clip to screen, so if we are out of the screen we
|
|
|
|
// shift the button to fit
|
|
|
|
if ( x < 0 )
|
|
|
|
x = 0;
|
|
|
|
if ( y < 0 )
|
|
|
|
y = 0;
|
|
|
|
if ( x + zsurf->w > sdlwindow->w )
|
|
|
|
x = sdlwindow->w - zsurf->w;
|
|
|
|
if ( y + zsurf->h > sdlwindow->h )
|
|
|
|
y = sdlwindow->h - zsurf->h;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Backup where to
|
|
|
|
showkeylastx = x;
|
|
|
|
showkeylasty = y;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Backup old surface
|
|
|
|
srect.x = x;
|
|
|
|
srect.y = y;
|
|
|
|
srect.w = zsurf->w;
|
|
|
|
srect.h = zsurf->h;
|
|
|
|
drect.x = 0;
|
|
|
|
drect.y = 0;
|
|
|
|
SDL_BlitSurface( sdlwindow, &srect, showkeylastsurf, &drect );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Blit the zoomed button
|
|
|
|
drect.x = x;
|
|
|
|
drect.y = y;
|
|
|
|
SDL_BlitSurface( zsurf, 0, sdlwindow, &drect );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Free zoomed surface
|
|
|
|
SDL_FreeSurface( zsurf );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Update
|
|
|
|
SDL_UpdateRect( sdlwindow, x, y, zsurf->w, zsurf->h );
|
|
|
|
}
|
|
|
|
void SDLUIHideKey() {
|
|
|
|
SDL_Rect drect;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( showkeylastsurf == 0 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
drect.x = showkeylastx;
|
|
|
|
drect.y = showkeylasty;
|
|
|
|
SDL_BlitSurface( showkeylastsurf, 0, sdlwindow, &drect );
|
|
|
|
|
|
|
|
// Update
|
|
|
|
SDL_UpdateRect( sdlwindow, showkeylastx, showkeylasty, showkeylastsurf->w,
|
|
|
|
showkeylastsurf->h );
|
|
|
|
|
|
|
|
// Free
|
|
|
|
SDL_FreeSurface( showkeylastsurf );
|
|
|
|
showkeylastsurf = 0;
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLUIFeedback() {
|
|
|
|
// This function should give some UI feedback to indicate that a key was
|
|
|
|
// pressed E.g. by beeping, vibrating or flashing something
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_Surface *surf1, *surf2;
|
|
|
|
surf1 =
|
|
|
|
SDL_CreateRGBSurface( SDL_SWSURFACE, sdlwindow->w, sdlwindow->h, 32,
|
|
|
|
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 );
|
|
|
|
surf2 =
|
|
|
|
SDL_CreateRGBSurface( SDL_SWSURFACE, sdlwindow->w, sdlwindow->h, 32,
|
|
|
|
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Copy screen
|
|
|
|
SDL_BlitSurface( sdlwindow, 0, surf1, 0 );
|
|
|
|
|
|
|
|
// Overlay something
|
|
|
|
SDL_FillRect( surf2, 0, 0x80000000 );
|
|
|
|
SDL_BlitSurface( surf2, 0, sdlwindow, 0 );
|
|
|
|
SDL_UpdateRect( sdlwindow, 0, 0, 0, 0 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_Delay( 20 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Restore screen
|
|
|
|
SDL_BlitSurface( surf1, 0, sdlwindow, 0 );
|
|
|
|
|
|
|
|
SDL_UpdateRect( sdlwindow, 0, 0, 0, 0 );
|
|
|
|
|
|
|
|
SDL_FreeSurface( surf1 );
|
|
|
|
SDL_FreeSurface( surf2 );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Simple 'show window' function
|
|
|
|
SDLWINDOW_t SDLCreateWindow( int x, int y, int w, int h, unsigned color,
|
|
|
|
int framewidth, int inverted ) {
|
|
|
|
SDLWINDOW_t win;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Backup the screen
|
|
|
|
win.oldsurf = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, 0x00ff0000,
|
|
|
|
0x0000ff00, 0x000000ff, 0xff000000 );
|
|
|
|
win.surf = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 32, 0x00ff0000,
|
|
|
|
0x0000ff00, 0x000000ff, 0xff000000 );
|
|
|
|
win.x = x;
|
|
|
|
win.y = y;
|
|
|
|
// Copy screen
|
|
|
|
SDL_Rect srect;
|
|
|
|
SDL_Rect drect;
|
|
|
|
srect.x = x;
|
|
|
|
srect.y = y;
|
|
|
|
srect.w = w;
|
|
|
|
srect.h = h;
|
|
|
|
drect.x = 0;
|
|
|
|
drect.y = 0;
|
|
|
|
drect.w = w;
|
|
|
|
drect.h = h;
|
|
|
|
SDL_BlitSurface( sdlwindow, &srect, win.oldsurf, &drect );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Draw window background
|
|
|
|
SDL_FillRect( win.surf, &drect, color );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Compute the frame color
|
|
|
|
int a, r, g, b;
|
|
|
|
int r2, g2, b2;
|
|
|
|
int contrast = 5;
|
|
|
|
unsigned colorlight, colordark;
|
|
|
|
SDLARGBTo( color, ( unsigned* )&a, ( unsigned* )&r, ( unsigned* )&g,
|
|
|
|
( unsigned* )&b );
|
|
|
|
r2 = r + r / contrast;
|
|
|
|
g2 = g + g / contrast;
|
|
|
|
b2 = b + b / contrast;
|
|
|
|
if ( r2 > 255 )
|
|
|
|
r2 = 255;
|
|
|
|
if ( g2 > 255 )
|
|
|
|
g2 = 255;
|
|
|
|
if ( b2 > 255 )
|
|
|
|
b2 = 255;
|
|
|
|
colorlight = SDLToARGB( a, r2, g2, b2 );
|
|
|
|
r2 = r - r / contrast;
|
|
|
|
g2 = g - g / contrast;
|
|
|
|
b2 = b - b / contrast;
|
|
|
|
if ( r2 < 0 )
|
|
|
|
r2 = 0;
|
|
|
|
if ( g2 < 0 )
|
|
|
|
g2 = 0;
|
|
|
|
if ( b2 < 0 )
|
|
|
|
b2 = 0;
|
|
|
|
colordark = SDLToARGB( a, r2, g2, b2 );
|
|
|
|
|
|
|
|
if ( inverted ) {
|
|
|
|
unsigned t = colorlight;
|
|
|
|
colorlight = colordark;
|
|
|
|
colordark = t;
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
printf( "color: %08X\n", color );
|
|
|
|
printf( "colorlight: %08X\n", colorlight );
|
|
|
|
printf( "colordark: %08X\n", colordark );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Draw the frame
|
|
|
|
int i;
|
|
|
|
for ( i = 0; i < framewidth; i++ ) {
|
|
|
|
lineColor( win.surf, 0, i, w - 2 - i, i,
|
|
|
|
SDLBGRA2ARGB( colorlight ) ); // Horizontal top
|
|
|
|
lineColor( win.surf, i, 0, i, h - 2 - i,
|
|
|
|
SDLBGRA2ARGB( colorlight ) ); // Vertical left
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
lineColor( win.surf, 1 + i, h - 1 - i, w - 1, h - 1 - i,
|
|
|
|
SDLBGRA2ARGB( colordark ) ); // Horizontal bottom
|
|
|
|
lineColor( win.surf, w - 1 - i, 1 + i, w - 1 - i, h - 1,
|
|
|
|
SDLBGRA2ARGB( colordark ) ); // Vertical right
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
return win;
|
|
|
|
}
|
|
|
|
void SDLShowWindow( SDLWINDOW_t* win ) {
|
|
|
|
// Blit the window
|
|
|
|
SDL_Rect srect;
|
|
|
|
SDL_Rect drect;
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = win->surf->w;
|
|
|
|
srect.h = win->surf->h;
|
|
|
|
drect.x = win->x;
|
|
|
|
drect.y = win->y;
|
|
|
|
drect.w = win->surf->w;
|
|
|
|
drect.h = win->surf->h;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_BlitSurface( win->surf, &srect, sdlwindow, &drect );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_UpdateRect( sdlwindow, 0, 0, 0, 0 );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLHideWindow( SDLWINDOW_t* win ) {
|
|
|
|
// Restore the screen
|
|
|
|
SDL_Rect srect;
|
|
|
|
SDL_Rect drect;
|
|
|
|
srect.x = 0;
|
|
|
|
srect.y = 0;
|
|
|
|
srect.w = win->oldsurf->w;
|
|
|
|
srect.h = win->oldsurf->h;
|
|
|
|
drect.x = win->x;
|
|
|
|
drect.y = win->y;
|
|
|
|
drect.w = win->oldsurf->w;
|
|
|
|
drect.h = win->oldsurf->h;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_BlitSurface( win->oldsurf, &srect, sdlwindow, &drect );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDL_UpdateRect( sdlwindow, 0, 0, 0, 0 );
|
|
|
|
SDL_FreeSurface( win->surf );
|
|
|
|
SDL_FreeSurface( win->oldsurf );
|
|
|
|
win->surf = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert a 32-bit aarrggbb number to individual components
|
|
|
|
void SDLARGBTo( unsigned color, unsigned* a, unsigned* r, unsigned* g,
|
|
|
|
unsigned* b ) {
|
|
|
|
*a = ( color >> 24 ) & 0xff;
|
|
|
|
*r = ( color >> 16 ) & 0xff;
|
|
|
|
*g = ( color >> 8 ) & 0xff;
|
|
|
|
*b = color & 0xff;
|
|
|
|
}
|
|
|
|
// Convert a,r,g,b to a 32-bit aarrggbb number
|
|
|
|
unsigned SDLToARGB( unsigned a, unsigned r, unsigned g, unsigned b ) {
|
|
|
|
return ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | ( b );
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLMessageBox( int w, int h, const char* title, const char* text[],
|
|
|
|
unsigned color, unsigned colortext, int center ) {
|
|
|
|
int x, y;
|
|
|
|
int framewidth = 3;
|
|
|
|
int texthspace = 9;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Compute the coordinates of the window (center on screen)
|
|
|
|
x = ( sdlwindow->w - w ) / 2;
|
|
|
|
y = ( sdlwindow->h - h ) / 2;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLWINDOW_t win;
|
|
|
|
printf( "ShowWindow\n" );
|
|
|
|
win = SDLCreateWindow( x, y, w, h, color, framewidth, 0 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
stringColor( win.surf, ( w - strlen( title ) * 8 ) / 2,
|
|
|
|
framewidth + texthspace, title, SDLBGRA2ARGB( colortext ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
int i, numlines;
|
|
|
|
for ( numlines = 0; text[ numlines ]; numlines++ )
|
|
|
|
; // Count number of lines
|
|
|
|
for ( i = 0; text[ i ]; i++ ) {
|
|
|
|
if ( center )
|
|
|
|
x = ( w - strlen( text[ i ] ) * 8 ) / 2;
|
|
|
|
else
|
|
|
|
x = framewidth + 8;
|
|
|
|
if ( 0 )
|
|
|
|
stringColor( win.surf, x, framewidth + 8 + 16 + i * texthspace,
|
|
|
|
text[ i ], SDLBGRA2ARGB( colortext ) );
|
|
|
|
else
|
|
|
|
stringColor( win.surf, x,
|
|
|
|
( h - numlines * texthspace ) / 2 + i * texthspace,
|
|
|
|
text[ i ], SDLBGRA2ARGB( colortext ) );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLShowWindow( &win );
|
|
|
|
SDLEventWaitClickOrKey();
|
|
|
|
SDLHideWindow( &win );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLEventWaitClickOrKey() {
|
|
|
|
SDL_Event event;
|
|
|
|
while ( 1 ) {
|
|
|
|
SDL_WaitEvent( &event );
|
|
|
|
switch ( event.type ) {
|
|
|
|
case SDL_QUIT:
|
|
|
|
return;
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
return;
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case SDL_KEYDOWN:
|
|
|
|
return;
|
|
|
|
break;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
void SDLShowInformation() {
|
|
|
|
const char* info_title = "x48ng - HP48 emulator";
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
const char* info_text[] = { //"12345678901234567890123456789012345",
|
|
|
|
"",
|
|
|
|
"License: GPL",
|
|
|
|
"",
|
|
|
|
"In order to work the emulator needs",
|
|
|
|
"the following files:",
|
|
|
|
" rom: an HP48 rom dump",
|
|
|
|
" ram: ram file",
|
|
|
|
" hp48: HP state file",
|
|
|
|
"",
|
|
|
|
"The following files are optional:",
|
|
|
|
" port1: card 1 memory",
|
|
|
|
" port2: card 2 memory",
|
|
|
|
"",
|
|
|
|
"These files must be in ~/.x48ng",
|
|
|
|
"",
|
|
|
|
0 };
|
|
|
|
SDLMessageBox( 310, 280, info_title, info_text, 0xf0c0c0e0, 0xff000000, 0 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
const char* info_text2[] = { //"12345678901234567890123456789012345",
|
|
|
|
"",
|
|
|
|
"Do a long key press (about 1 sec)",
|
|
|
|
"to keep the key down (e.g. for",
|
|
|
|
"ON-C, ON-+, ON-A-F).",
|
|
|
|
"",
|
|
|
|
"There are issues with throttling",
|
|
|
|
"and key repeat rate. Therefore key",
|
|
|
|
"repeat for arrows and backspace is",
|
|
|
|
"disabled.",
|
|
|
|
"",
|
|
|
|
0 };
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
SDLMessageBox( 310, 280, info_title, info_text2, 0xf0c0c0e0, 0xff000000,
|
|
|
|
0 );
|
|
|
|
}
|
|
|
|
#endif
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
int get_ui_event( void ) {
|
|
|
|
#if defined( GUI_IS_X11 )
|
|
|
|
XEvent xev;
|
|
|
|
XClientMessageEvent* cm;
|
|
|
|
int i, wake, bufs = 2;
|
|
|
|
char buf[ 2 ];
|
|
|
|
KeySym sym;
|
|
|
|
// int button_expose;
|
|
|
|
// static int button_leave = -1;
|
|
|
|
static int release_pending = 0;
|
|
|
|
static XKeyEvent release_event;
|
|
|
|
static Time last_release_time = 0;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
wake = 0;
|
|
|
|
if ( paste_last_key ) {
|
|
|
|
button_released( paste[ paste_count - 1 ] );
|
|
|
|
paste_last_key = 0;
|
|
|
|
return 1;
|
|
|
|
} else if ( paste_count < paste_size ) {
|
|
|
|
button_pressed( paste[ paste_count ] );
|
|
|
|
paste_last_key = 1;
|
|
|
|
paste_count++;
|
|
|
|
return 1;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( release_pending ) {
|
|
|
|
i = XLookupString( &release_event, buf, bufs, &sym, NULL );
|
|
|
|
wake = decode_key( ( XEvent* )&release_event, sym, buf, i );
|
|
|
|
release_pending = 0;
|
|
|
|
return wake;
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
do {
|
|
|
|
while ( XPending( dpy ) > 0 ) {
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
XNextEvent( dpy, &xev );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
switch ( ( int )xev.type ) {
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case KeyPress:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( 0 && release_pending ) {
|
|
|
|
printf( "xxx release_pending\n" );
|
|
|
|
}
|
|
|
|
release_pending = 0;
|
|
|
|
if ( ( xev.xkey.time - last_release_time ) <= 1 ) {
|
|
|
|
release_pending = 0;
|
|
|
|
break;
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
i = XLookupString( &xev.xkey, buf, bufs, &sym, NULL );
|
|
|
|
wake = decode_key( &xev, sym, buf, i );
|
|
|
|
first_key = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KeyRelease:
|
|
|
|
|
|
|
|
i = XLookupString( &xev.xkey, buf, bufs, &sym, NULL );
|
|
|
|
first_key = 0;
|
|
|
|
release_pending = 1;
|
|
|
|
last_release_time = xev.xkey.time;
|
|
|
|
memcpy( &release_event, &xev, sizeof( XKeyEvent ) );
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case NoExpose:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case Expose:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( xev.xexpose.count == 0 ) {
|
|
|
|
if ( xev.xexpose.window == disp.win ) {
|
|
|
|
DrawDisp();
|
|
|
|
} else if ( xev.xexpose.window == iconW ) {
|
|
|
|
DrawIcon();
|
|
|
|
} else if ( xev.xexpose.window == mainW ) {
|
|
|
|
DrawKeypad( &keypad );
|
|
|
|
} else
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
|
|
|
if ( xev.xexpose.window == buttons[ i ].xwin ) {
|
|
|
|
DrawButton( i );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case UnmapNotify:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
disp.mapped = 0;
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case MapNotify:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( !disp.mapped ) {
|
|
|
|
disp.mapped = 1;
|
|
|
|
update_display();
|
|
|
|
redraw_annunc();
|
|
|
|
}
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case ButtonPress:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( xev.xbutton.subwindow == disp.win ) {
|
|
|
|
if ( xev.xbutton.button == Button2 ) {
|
|
|
|
if ( xev.xbutton.subwindow == disp.win ) {
|
|
|
|
int x;
|
|
|
|
int flag = 0;
|
|
|
|
char* paste_in = XFetchBuffer( dpy, &x, 0 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
char* p = paste_in;
|
|
|
|
if ( x > MAX_PASTE ) {
|
|
|
|
x = 0;
|
|
|
|
printf( "input too long. limit is %d "
|
|
|
|
"characters\n",
|
|
|
|
MAX_PASTE );
|
|
|
|
}
|
|
|
|
paste_count = 0;
|
|
|
|
paste_size = 0;
|
|
|
|
while ( x-- ) {
|
|
|
|
char c = *p++;
|
|
|
|
switch ( c ) {
|
|
|
|
case '.':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_PERIOD;
|
|
|
|
break;
|
|
|
|
case '0':
|
|
|
|
paste[ paste_size++ ] = BUTTON_0;
|
|
|
|
break;
|
|
|
|
case '1':
|
|
|
|
paste[ paste_size++ ] = BUTTON_1;
|
|
|
|
break;
|
|
|
|
case '2':
|
|
|
|
paste[ paste_size++ ] = BUTTON_2;
|
|
|
|
break;
|
|
|
|
case '3':
|
|
|
|
paste[ paste_size++ ] = BUTTON_3;
|
|
|
|
break;
|
|
|
|
case '4':
|
|
|
|
paste[ paste_size++ ] = BUTTON_4;
|
|
|
|
break;
|
|
|
|
case '5':
|
|
|
|
paste[ paste_size++ ] = BUTTON_5;
|
|
|
|
break;
|
|
|
|
case '6':
|
|
|
|
paste[ paste_size++ ] = BUTTON_6;
|
|
|
|
break;
|
|
|
|
case '7':
|
|
|
|
paste[ paste_size++ ] = BUTTON_7;
|
|
|
|
break;
|
|
|
|
case '8':
|
|
|
|
paste[ paste_size++ ] = BUTTON_8;
|
|
|
|
break;
|
|
|
|
case '9':
|
|
|
|
paste[ paste_size++ ] = BUTTON_9;
|
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
paste[ paste_size++ ] = BUTTON_SHR;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_PERIOD;
|
|
|
|
break;
|
|
|
|
case '!':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
paste[ paste_size++ ] = BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_DEL;
|
|
|
|
break;
|
|
|
|
case '+':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
paste[ paste_size++ ] = BUTTON_PLUS;
|
|
|
|
break;
|
|
|
|
case '-':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_MINUS;
|
|
|
|
break;
|
|
|
|
case '*':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
paste[ paste_size++ ] = BUTTON_MUL;
|
|
|
|
break;
|
|
|
|
case '/':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
paste[ paste_size++ ] = BUTTON_DIV;
|
|
|
|
break;
|
|
|
|
case ' ':
|
|
|
|
paste[ paste_size++ ] = 47;
|
|
|
|
break;
|
|
|
|
case '(':
|
|
|
|
paste[ paste_size++ ] = BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_DIV;
|
|
|
|
break;
|
|
|
|
case '[':
|
|
|
|
paste[ paste_size++ ] = BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_MUL;
|
|
|
|
break;
|
|
|
|
case '<':
|
|
|
|
if ( x > 1 && *p == '<' ) {
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_MINUS;
|
|
|
|
x--;
|
|
|
|
p++;
|
|
|
|
} else {
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '{':
|
|
|
|
paste[ paste_size++ ] = BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_PLUS;
|
|
|
|
break;
|
|
|
|
case ')':
|
|
|
|
case ']':
|
|
|
|
case '}':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_RIGHT;
|
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
if ( x > 1 && *p == '>' ) {
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_RIGHT;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_RIGHT;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_RIGHT;
|
|
|
|
x--;
|
|
|
|
p++;
|
|
|
|
} else {
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHR;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '#':
|
|
|
|
paste[ paste_size++ ] = BUTTON_SHR;
|
|
|
|
paste[ paste_size++ ] = BUTTON_DIV;
|
|
|
|
break;
|
|
|
|
case '_':
|
|
|
|
paste[ paste_size++ ] = BUTTON_SHR;
|
|
|
|
paste[ paste_size++ ] = BUTTON_MUL;
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
if ( flag & 1 ) {
|
|
|
|
flag &= ~1;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_RIGHT;
|
|
|
|
} else {
|
|
|
|
flag |= 1;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHR;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_MINUS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ':':
|
|
|
|
if ( flag & 2 ) {
|
|
|
|
flag &= ~2;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_RIGHT;
|
|
|
|
} else {
|
|
|
|
flag |= 2;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHR;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_PLUS;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '\'':
|
|
|
|
if ( flag & 4 ) {
|
|
|
|
flag &= ~4;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_RIGHT;
|
|
|
|
} else {
|
|
|
|
flag |= 4;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_COLON;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
case 'A':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_A;
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
case 'B':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_B;
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
case 'C':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_C;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
case 'D':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_D;
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
case 'E':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_E;
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
case 'F':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_F;
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
|
|
case 'G':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_MTH;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
case 'H':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_PRG;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
case 'I':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_CST;
|
|
|
|
break;
|
|
|
|
case 'j':
|
|
|
|
case 'J':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_VAR;
|
|
|
|
break;
|
|
|
|
case 'k':
|
|
|
|
case 'K':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_UP;
|
|
|
|
break;
|
|
|
|
case 'l':
|
|
|
|
case 'L':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_NXT;
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case 'm':
|
|
|
|
case 'M':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_COLON;
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
case 'N':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_STO;
|
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
case 'O':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_EVAL;
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
case 'P':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_LEFT;
|
|
|
|
break;
|
|
|
|
case 'q':
|
|
|
|
case 'Q':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_DOWN;
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
case 'R':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_RIGHT;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
case 'S':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_SIN;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
case 'T':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_COS;
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
case 'U':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_TAN;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
case 'V':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_SQRT;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
case 'W':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_POWER;
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
case 'X':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_INV;
|
|
|
|
break;
|
|
|
|
case 'y':
|
|
|
|
case 'Y':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_NEG;
|
|
|
|
break;
|
|
|
|
case 'z':
|
|
|
|
case 'Z':
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_ALPHA;
|
|
|
|
if ( islower( c ) )
|
|
|
|
paste[ paste_size++ ] =
|
|
|
|
BUTTON_SHL;
|
|
|
|
paste[ paste_size++ ] = BUTTON_EEX;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf( "unknown %c %d\n", c, *p );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( paste_in )
|
|
|
|
XFree( paste_in );
|
|
|
|
if ( paste_size ) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ( xev.xbutton.button == Button3 ) {
|
|
|
|
/* TODO Make cut from the screen work. */
|
|
|
|
get_stack();
|
|
|
|
} else {
|
|
|
|
/* printf("In display %d\n", xev.xbutton.button); */
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
} else {
|
|
|
|
if ( xev.xbutton.button == Button1 ||
|
|
|
|
xev.xbutton.button == Button2 ||
|
|
|
|
xev.xbutton.button == Button3 ) {
|
|
|
|
for ( i = BUTTON_A; i <= LAST_BUTTON; i++ ) {
|
|
|
|
if ( xev.xbutton.subwindow ==
|
|
|
|
buttons[ i ].xwin ) {
|
|
|
|
if ( buttons[ i ].pressed ) {
|
|
|
|
if ( xev.xbutton.button == Button3 ) {
|
|
|
|
button_released( i );
|
|
|
|
DrawButton( i );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
last_button = i;
|
|
|
|
button_pressed( i );
|
|
|
|
wake = 1;
|
|
|
|
first_key = 1;
|
|
|
|
DrawButton( i );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
2023-05-03 09:40:52 +02:00
|
|
|
}
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case ButtonRelease:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
first_key = 0;
|
|
|
|
if ( xev.xbutton.button == Button1 ) {
|
|
|
|
button_release_all();
|
|
|
|
}
|
|
|
|
if ( xev.xbutton.button == Button2 ) {
|
|
|
|
if ( last_button >= 0 ) {
|
|
|
|
button_released( last_button );
|
|
|
|
DrawButton( last_button );
|
|
|
|
}
|
|
|
|
last_button = -1;
|
|
|
|
}
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case FocusOut:
|
|
|
|
first_key = 0;
|
|
|
|
button_release_all();
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case MappingNotify:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
switch ( xev.xmapping.request ) {
|
|
|
|
case MappingModifier:
|
|
|
|
case MappingKeyboard:
|
|
|
|
XRefreshKeyboardMapping( &xev.xmapping );
|
|
|
|
break;
|
|
|
|
case MappingPointer:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case EnterNotify:
|
|
|
|
case LeaveNotify:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case ClientMessage:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
cm = ( XClientMessageEvent* )&xev;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( cm->message_type == wm_protocols ) {
|
|
|
|
if ( cm->data.l[ 0 ] == wm_delete_window ) {
|
|
|
|
/*
|
|
|
|
* Quit selected from window managers menu
|
|
|
|
*/
|
|
|
|
exit_x48( 1 );
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( cm->data.l[ 0 ] == wm_save_yourself ) {
|
|
|
|
save_command_line();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
default:
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
#ifdef DEBUG_XEVENT
|
|
|
|
printf( "Event: %d\n", xev.type );
|
|
|
|
#endif
|
|
|
|
case KeymapNotify:
|
|
|
|
case ConfigureNotify:
|
|
|
|
case ReparentNotify:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while ( first_key > 1 );
|
|
|
|
if ( first_key ) {
|
|
|
|
first_key++;
|
|
|
|
}
|
|
|
|
return wake;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
#elif defined( GUI_IS_SDL1 )
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// printf("Get event\n");
|
|
|
|
SDL_Event event;
|
|
|
|
int hpkey;
|
|
|
|
int rv;
|
|
|
|
static int lasthpkey = -1; // last key that was pressed or -1 for none
|
|
|
|
static int lastticks =
|
|
|
|
-1; // time at which a key was pressed or -1 if timer expired
|
|
|
|
static int lastislongpress = 0; // last key press was a long press
|
|
|
|
/* static unsigned ctr = 0; */
|
|
|
|
static int keyispressed = -1; // Indicate if a key is being held down by
|
|
|
|
// a finger (not set for long presses)
|
|
|
|
static int keyneedshow = 0; // Indicates if the buttons need to be shown
|
|
|
|
static int dispupdate_t1 = -1,
|
|
|
|
dispupdate_t2; // Logic to display at regular intervals
|
|
|
|
// printf("SDLGetEvent %08X\n",ctr++);
|
|
|
|
/* unsigned t1, t2; */
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
/* unsigned ticks = SDL_GetTicks (); */
|
|
|
|
// printf("%u\n",ticks);
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// make keys that last only one cycle
|
|
|
|
// button_release_all();
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
rv = 0; // nothing to do
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Check whether long pres on key
|
|
|
|
if ( lastticks > 0 && ( SDL_GetTicks() - lastticks > 750 ) ) {
|
|
|
|
// time elapsed
|
|
|
|
printf( "Timer expired\n" );
|
|
|
|
lastticks = -1;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Check that the mouse is still on the same last key
|
|
|
|
int x, y, state;
|
|
|
|
// int hpkeykbd;
|
|
|
|
// char *kstate;
|
|
|
|
state = SDL_GetMouseState( &x, &y );
|
|
|
|
// kstate = SDL_GetKeyState(0);
|
|
|
|
// hpkeykbd = SDLKeyToKey(event.key.keysym.sym);
|
|
|
|
// if(state&SDL_BUTTON(1) && ((SDLCoordinateToKey(x,y)==lasthpkey)
|
|
|
|
// ||()
|
|
|
|
// ))
|
|
|
|
if ( state & SDL_BUTTON( 1 ) &&
|
|
|
|
SDLCoordinateToKey( x, y ) == lasthpkey ) {
|
|
|
|
lastislongpress = 1;
|
|
|
|
printf( "\tlong press\n" );
|
|
|
|
SDLUIFeedback();
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Iterate as long as there are events
|
|
|
|
// while( SDL_PollEvent( &event ) )
|
|
|
|
if ( SDL_PollEvent( &event ) ) {
|
|
|
|
// printf("PollEvent got %d\n",event.type);
|
|
|
|
switch ( event.type ) {
|
|
|
|
case SDL_QUIT:
|
|
|
|
printf( "Got SDL_QUIT event\n" );
|
|
|
|
exit_x48( 0 );
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Mouse move: react to state changes in the buttons that are
|
|
|
|
// pressed
|
|
|
|
case SDL_MOUSEMOTION:
|
|
|
|
hpkey = SDLCoordinateToKey( event.motion.x, event.motion.y );
|
|
|
|
// printf("Mouse move %d,%d: %d hpkey: %d lasthpkey %d long
|
|
|
|
// %d\n", event.motion.x, event.motion.y,
|
|
|
|
// event.motion.state, hpkey,lasthpkey,lastislongpress);
|
|
|
|
if ( event.motion.state & SDL_BUTTON( 1 ) ) {
|
|
|
|
// Mouse moves on a key different from the last key
|
|
|
|
// (state change):
|
|
|
|
// - release last (if last was pressed)
|
|
|
|
// - press new (if new is pressed)
|
|
|
|
if ( hpkey != lasthpkey ) {
|
|
|
|
keyispressed = hpkey;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( lasthpkey != -1 ) {
|
|
|
|
if ( !lastislongpress ) {
|
|
|
|
// button_released(lasthpkey);
|
|
|
|
button_release_all();
|
|
|
|
rv = 1;
|
|
|
|
SDLUIFeedback();
|
|
|
|
printf( "release all\n" );
|
|
|
|
}
|
|
|
|
// Stop timer, clear long key press
|
|
|
|
lastticks = -1;
|
|
|
|
lastislongpress = 0;
|
|
|
|
}
|
|
|
|
if ( hpkey != -1 ) {
|
|
|
|
if ( !buttons[ hpkey ]
|
|
|
|
.pressed ) // If a key is down, it
|
|
|
|
// can't be down another
|
|
|
|
// time
|
|
|
|
{
|
|
|
|
button_pressed( hpkey );
|
|
|
|
rv = 1;
|
|
|
|
// Start timer
|
|
|
|
lastticks = SDL_GetTicks();
|
|
|
|
SDLUIFeedback();
|
|
|
|
printf( "press %d\n", hpkey );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lasthpkey = hpkey;
|
|
|
|
}
|
|
|
|
if ( hpkey == -1 ) // Needed to avoid pressing and moving
|
|
|
|
// outside of a button releases
|
|
|
|
lasthpkey = -1;
|
|
|
|
|
|
|
|
break;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
// React only to left mouse button
|
|
|
|
if ( event.type == SDL_MOUSEBUTTONDOWN &&
|
|
|
|
event.button.button == SDL_BUTTON_LEFT ) {
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( event.button.y < DISPLAY_OFFSET_Y ||
|
|
|
|
event.button.y <
|
|
|
|
48 ) // If we resized the screen, then there's
|
|
|
|
// no space above offset_y...clicking on
|
|
|
|
// the screen has to do something
|
|
|
|
SDLShowInformation();
|
|
|
|
// printf("l button up/down at %d %d. hpkey: %d lastkey:
|
|
|
|
// %d long:
|
|
|
|
// %d\n",event.button.x,event.button.y,hpkey,lasthpkey,lastislongpress);
|
|
|
|
}
|
|
|
|
hpkey = SDLCoordinateToKey( event.button.x, event.button.y );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( hpkey !=
|
|
|
|
-1 ) // React to mouse up/down when click over a button
|
|
|
|
{
|
|
|
|
if ( event.type == SDL_MOUSEBUTTONDOWN ) {
|
|
|
|
keyispressed = hpkey;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( !buttons[ hpkey ].pressed ) // Key can't be pressed
|
|
|
|
// when down
|
|
|
|
{
|
|
|
|
button_pressed( hpkey );
|
|
|
|
rv = 1;
|
|
|
|
lasthpkey = hpkey;
|
|
|
|
// Start timer
|
|
|
|
lastticks = SDL_GetTicks();
|
|
|
|
SDLUIFeedback();
|
|
|
|
printf( "press %d\n", hpkey );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
keyispressed = -1;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( !lastislongpress ) {
|
|
|
|
button_release_all();
|
|
|
|
rv = 1;
|
|
|
|
lasthpkey = -1; // No key is pressed anymore
|
|
|
|
SDLUIFeedback();
|
|
|
|
printf( "release all\n" );
|
|
|
|
}
|
2023-05-02 14:40:02 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Stop timer, clear long key press
|
|
|
|
lastticks = -1;
|
|
|
|
lastislongpress = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_KEYDOWN:
|
|
|
|
case SDL_KEYUP:
|
|
|
|
printf( "Key: %d hpkey: %d\n", event.key.keysym.sym,
|
|
|
|
SDLKeyToKey( event.key.keysym.sym ) );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
if ( event.type == SDL_KEYDOWN &&
|
|
|
|
event.key.keysym.sym == SDLK_F1 ) {
|
|
|
|
SDLShowInformation();
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
hpkey = SDLKeyToKey( event.key.keysym.sym );
|
|
|
|
if ( hpkey != -1 ) {
|
|
|
|
if ( event.type == SDL_KEYDOWN ) {
|
|
|
|
keyispressed = hpkey;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Avoid pressing if it is already pressed
|
|
|
|
if ( !buttons[ hpkey ].pressed ) {
|
|
|
|
button_pressed( hpkey );
|
|
|
|
rv = 1;
|
|
|
|
SDLUIFeedback();
|
|
|
|
printf( "press kbd %d\n", hpkey );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
keyispressed = -1;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
button_released( hpkey );
|
|
|
|
rv = 1;
|
|
|
|
SDLUIFeedback();
|
|
|
|
printf( "release kbd %d\n", hpkey );
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Display button being pressed, if any
|
|
|
|
/* t1 = SDL_GetTicks (); */
|
|
|
|
SDLUIShowKey( keyispressed );
|
|
|
|
/* t2 = SDL_GetTicks (); */
|
|
|
|
// printf("Draw zoomed button: %03d\n",t2-t1);
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// If we press long, then the button releases makes SDLUIShowKey restore
|
|
|
|
// the old key, but rv does not indicate that we need to update the
|
|
|
|
// buttons. Therefore we save it here
|
|
|
|
if ( rv )
|
|
|
|
keyneedshow = 1;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// Redraw the keyboard only if there is a button state change and no
|
|
|
|
// button is pressed (otherwise it overwrites the zoomed button)
|
|
|
|
if ( keyneedshow && keyispressed == -1 ) {
|
|
|
|
keyneedshow = 0;
|
|
|
|
/* t1 = SDL_GetTicks (); */
|
|
|
|
SDLDrawButtons();
|
|
|
|
/* t2 = SDL_GetTicks (); */
|
|
|
|
// printf("Draw all buttons: %03d\n",t2-t1);
|
2023-04-30 16:34:53 +02:00
|
|
|
}
|
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
#ifdef DELAYEDDISPUPDATE
|
|
|
|
dispupdate_t2 = SDL_GetTicks();
|
|
|
|
if ( dispupdate_t2 - dispupdate_t1 > DISPUPDATEINTERVAL ) {
|
|
|
|
/* t1 = SDL_GetTicks (); */
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
int xoffset = DISPLAY_OFFSET_X + 5;
|
|
|
|
int yoffset = DISPLAY_OFFSET_Y + 20;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// LCD
|
|
|
|
SDL_UpdateRect( sdlwindow, xoffset, yoffset, 131 * 2, 64 * 2 );
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// SDL_UpdateRect(sdlwindow,0,0,0,0);
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
/* t2 = SDL_GetTicks (); */
|
|
|
|
// printf("Update rect %03d\t%03d\n",ctr++,t2-t1);
|
|
|
|
dispupdate_t1 = dispupdate_t2;
|
|
|
|
}
|
|
|
|
#endif
|
2023-04-30 16:34:53 +02:00
|
|
|
|
2023-05-03 09:40:52 +02:00
|
|
|
// return rv;
|
|
|
|
return 1;
|
2023-04-30 16:34:53 +02:00
|
|
|
|
|
|
|
#endif
|
2023-05-03 09:40:52 +02:00
|
|
|
}
|