mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-02-07 02:52:42 +08:00
implementation of random IAL engine
This commit is contained in:
260
src/ial/random.c
260
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 <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 */
|
||||
|
||||
Reference in New Issue
Block a user