From acb9b95bc6ff70c0b499383dad659b7282f1cf0f Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Mon, 17 Jun 2019 12:34:16 +0800 Subject: [PATCH] implementation of random IAL engine --- src/ial/random.c | 260 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 231 insertions(+), 29 deletions(-) diff --git a/src/ial/random.c b/src/ial/random.c index b55e8224..7c6e1800 100644 --- a/src/ial/random.c +++ b/src/ial/random.c @@ -61,7 +61,7 @@ ** - tablet_pad: tablet pad. ** - switch: switch. ** -** The MiniGUI ETC key `random.maxkeycode` specify the maximal key code +** The MiniGUI ETC key `random.maxkeycode` specifies the maximal key code ** which can be generated by the engine. ** ** For invalid `random.eventtyps` and `random.maxkeycord key value, @@ -77,28 +77,218 @@ #include #include +#define _DEBUG #include "common.h" #ifdef _MGIAL_RANDOM +#include +#include + #include "minigui.h" #include "misc.h" #include "ial.h" #include "random.h" +#define BTN_NONE 0 + +#ifdef __LINUX__ +#include +#else + +/* copied from linux/input-event-codes.h */ +#define BTN_LEFT 0x110 +#define BTN_RIGHT 0x111 +#define BTN_MIDDLE 0x112 +#endif + +enum _random_event_type { + RANDOM_EVENT_NONE, + RANDOM_EVENT_WAIT, + RANDOM_EVENT_MOUSE_MOTION, + RANDOM_EVENT_MOUSE_BUTTON, + RANDOM_EVENT_KEYBOARD_KEY, +}; + +struct _random_event { + enum _random_event_type type; +}; + +typedef void* (*op_start_event_machine)(void); +typedef void (*op_stop_event_machine)(void* machine); +typedef const struct _random_event* (*op_generate_event)(void* machine); + enum _button_state { BUTTON_STATE_RELEASED, BUTTON_STATE_PRESSED, }; -struct _random_event { - int type; +enum _key_state { + KEY_STATE_RELEASED, + KEY_STATE_PRESSED, }; +/* state machine for mouse */ +struct _mouse_event { + struct _random_event event; + uint32_t button; + enum _button_state state; + int dx, dy; +}; + +enum _mouse_op_type { + MOUSE_OP_IDLE = 0, + MOUSE_OP_MOVE, + MOUSE_OP_CLICK, + MOUSE_OP_PRESSED_MOVE, + MOUSE_OP_COUNT, +}; + +struct _mouse_event_machine { + struct _mouse_event event; + enum _mouse_op_type op_type; + int op_sec; + time_t op_start; + + uint32_t btn_sel; + uint32_t btn_down; +}; + +static void* start_event_machine_mouse(void) +{ + struct _mouse_event_machine* machine; + machine = calloc(1, sizeof (struct _mouse_event_machine)); + + machine->op_type = MOUSE_OP_IDLE; + machine->op_sec = random() % 5; + machine->op_start = time(NULL); + return machine; +} + +static void stop_event_machine_mouse(void* machine) +{ + if (machine) + free(machine); +} + +static const struct _random_event* generate_event_mouse(void* machine) +{ + struct _mouse_event_machine* my_machine = + (struct _mouse_event_machine*)machine; + time_t now = time(NULL); + + memset(&my_machine->event, 0, sizeof(my_machine->event)); + + if ((now - my_machine->op_start) > my_machine->op_sec && + my_machine->btn_down == BTN_NONE) { + my_machine->op_type = now % MOUSE_OP_COUNT; + my_machine->op_sec = random() % 5; + my_machine->op_start = time(NULL); + + switch (now % 5) { + case 0: + my_machine->btn_sel = BTN_RIGHT; + break; + case 1: + my_machine->btn_sel = BTN_MIDDLE; + break; + default: /* 60% possibility to choose the left button. */ + my_machine->btn_sel = BTN_LEFT; + break; + } + + __mg_os_time_delay(100); + my_machine->event.event.type = RANDOM_EVENT_NONE; + goto ret; + } + + /* valid operation */ + if ((GetTickCount() % 5)) { + // 80% possibility to wait for a new event. + __mg_os_time_delay(10); + my_machine->event.event.type = RANDOM_EVENT_WAIT; + goto ret; + } + + switch (my_machine->op_type) { + case MOUSE_OP_IDLE: + my_machine->event.event.type = RANDOM_EVENT_WAIT; + break; + + case MOUSE_OP_MOVE: + my_machine->event.event.type = RANDOM_EVENT_MOUSE_MOTION; + my_machine->event.dx = random() % 100 - 50; + my_machine->event.dy = random() % 100 - 50; + break; + + case MOUSE_OP_CLICK: + if (my_machine->btn_down == BTN_NONE) { + my_machine->btn_down = my_machine->btn_sel; + + my_machine->event.event.type = RANDOM_EVENT_MOUSE_BUTTON; + my_machine->event.button = my_machine->btn_down; + my_machine->event.state = BUTTON_STATE_PRESSED; + } + else { + my_machine->event.event.type = RANDOM_EVENT_MOUSE_BUTTON; + my_machine->event.button = my_machine->btn_down; + my_machine->event.state = BUTTON_STATE_RELEASED; + + my_machine->btn_down = BTN_NONE; + } + break; + + case MOUSE_OP_PRESSED_MOVE: + if (my_machine->btn_down == BTN_NONE) { + my_machine->btn_down = my_machine->btn_sel; + + my_machine->event.event.type = RANDOM_EVENT_MOUSE_BUTTON; + my_machine->event.button = my_machine->btn_down; + my_machine->event.state = BUTTON_STATE_PRESSED; + } + else if ((GetTickCount() % 5) == 0) { + my_machine->event.event.type = RANDOM_EVENT_MOUSE_BUTTON; + my_machine->event.button = my_machine->btn_down; + my_machine->event.state = BUTTON_STATE_RELEASED; + + my_machine->btn_down = BTN_NONE; + } + else { + my_machine->event.event.type = RANDOM_EVENT_MOUSE_MOTION; + my_machine->event.dx = random() % 100 - 50; + my_machine->event.dy = random() % 100 - 50; + } + break; + + default: + assert(0); + break; + } + +ret: + return &my_machine->event.event; +} + +static inline struct _mouse_event* get_mouse_event(struct _random_event* event) +{ + if (event->type != RANDOM_EVENT_MOUSE_MOTION && + event->type != RANDOM_EVENT_MOUSE_BUTTON) + return NULL; + + return (struct _mouse_event*)event; +} + static struct _event_state_machine { const char* name; + op_start_event_machine start_machine; + op_stop_event_machine stop_machine; + op_generate_event generate_event; + void* machine; } event_state_machines [] = { - { "mouse", }, + { "mouse", + start_event_machine_mouse, + stop_event_machine_mouse, + generate_event_mouse}, { "keyboard", }, { "joystick", }, { "button", }, @@ -116,7 +306,9 @@ struct _random_input_contxt { int mouse_x, mouse_y, mouse_button; int nr_keys, last_keycode; char* kbd_state; + struct _event_state_machine *esm [TABLESIZE(event_state_machines)]; + int nr_machines; }; static struct _random_input_contxt my_ctxt; @@ -128,15 +320,6 @@ static void mouse_setrange (int newminx, int newminy, int newmaxx, int newmaxy) my_ctxt.min_y = newminy; my_ctxt.max_y = newmaxy; - if (my_ctxt.mouse_x < my_ctxt.min_x) - my_ctxt.mouse_x = my_ctxt.min_x; - if (my_ctxt.mouse_x > my_ctxt.max_x) - my_ctxt.mouse_x = my_ctxt.max_x; - if (my_ctxt.mouse_y < my_ctxt.min_y) - my_ctxt.mouse_y = my_ctxt.min_y; - if (my_ctxt.mouse_y > my_ctxt.max_y) - my_ctxt.mouse_y = my_ctxt.max_y; - my_ctxt.mouse_x = (my_ctxt.min_x + my_ctxt.max_x) / 2; my_ctxt.mouse_y = (my_ctxt.min_y + my_ctxt.max_y) / 2; } @@ -235,16 +418,6 @@ static BOOL on_new_mouse_pos (double x, double y) return TRUE; } -#ifdef __LINUX__ -#include -#else - -/* copied from linux/input-event-codes.h */ -#define BTN_LEFT 0x110 -#define BTN_RIGHT 0x111 -#define BTN_MIDDLE 0x112 -#endif - static BOOL on_mouse_button_changed (uint32_t button, enum _button_state state) { @@ -288,6 +461,7 @@ static BOOL on_mouse_button_changed (uint32_t button, static struct _random_event* get_random_event(struct _random_input_contxt* ctxt) { + return NULL; } @@ -317,7 +491,7 @@ BOOL InitRandomInput (INPUT* input, const char* mdev, const char* mtype) { char logfile[MAX_PATH + 1]; char eventtypes[LEN_EVENT_TYPES + 1]; - int i, n; + int i; if (GetMgEtcValue ("random", "logfile", logfile, MAX_PATH) == ETC_OK) { my_ctxt.log_fp = fopen(logfile, "a"); @@ -349,14 +523,24 @@ BOOL InitRandomInput (INPUT* input, const char* mdev, const char* mtype) strcpy(eventtypes, "mouse"); } - n = 0; + my_ctxt.nr_machines = 0; for (i = 0; i < TABLESIZE(event_state_machines); i++) { if (strstr(eventtypes, event_state_machines[i].name)) { - my_ctxt.esm[n] = event_state_machines + i; - n++; + struct _event_state_machine* machine = event_state_machines + i; + + if (machine->start_machine && + (machine->machine = machine->start_machine())) { + my_ctxt.esm[my_ctxt.nr_machines] = machine; + _DBG_PRINTF("IAL>RANDOM: start event machine for %s: %p\n", + event_state_machines[i].name, + my_ctxt.esm[my_ctxt.nr_machines]->machine); + my_ctxt.nr_machines++; + } } } + assert(my_ctxt.nr_machines > 0); + input->update_mouse = mouse_update; input->get_mouse_xy = mouse_getxy; input->set_mouse_xy = mouse_setxy; @@ -378,10 +562,28 @@ BOOL InitRandomInput (INPUT* input, const char* mdev, const char* mtype) void TermRandomInput (void) { - if (my_ctxt.log_fp) + int i; + + for (i = 0; i < TABLESIZE(event_state_machines); i++) { + if (my_ctxt.esm[i]->machine) { + if (my_ctxt.esm[i]->stop_machine) + my_ctxt.esm[i]->stop_machine(my_ctxt.esm[i]->machine); + else + free (my_ctxt.esm[i]->machine); + + my_ctxt.esm[i]->machine = NULL; + } + } + + if (my_ctxt.log_fp) { fclose(my_ctxt.log_fp); - if (my_ctxt.kbd_state) + my_ctxt.log_fp = NULL; + } + + if (my_ctxt.kbd_state) { free(my_ctxt.kbd_state); + my_ctxt.kbd_state = NULL; + } } #endif /* _MGIAL_RANDOM */