implementation of random IAL engine

This commit is contained in:
Vincent Wei
2019-06-17 12:34:16 +08:00
parent 60f07ae26a
commit acb9b95bc6

View File

@@ -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 <stdlib.h>
#include <string.h>
#define _DEBUG
#include "common.h"
#ifdef _MGIAL_RANDOM
#include <time.h>
#include <sys/time.h>
#include "minigui.h"
#include "misc.h"
#include "ial.h"
#include "random.h"
#define BTN_NONE 0
#ifdef __LINUX__
#include <linux/input-event-codes.h>
#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 <linux/input-event-codes.h>
#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 */