mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-02-07 02:52:42 +08:00
framework of new random enigne
This commit is contained in:
396
src/ial/random.c
396
src/ial/random.c
@@ -67,8 +67,10 @@
|
||||
** For invalid `random.eventtyps` and `random.maxkeycord key value,
|
||||
** use `mouse` and `NR_KEYS` respectively.
|
||||
**
|
||||
** This engine maintains a state machine for input events, and
|
||||
** generates a reasonable event sequence for each event type.
|
||||
** This engine maintains a state machine for each input event type, and
|
||||
** generates a reasonable event sequence for each type. If and only if
|
||||
** an event sequence finished or cancelled, the engine switch to another
|
||||
** event type randomly.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -84,169 +86,282 @@
|
||||
#include "ial.h"
|
||||
#include "random.h"
|
||||
|
||||
static unsigned char kbd_state [NR_KEYS];
|
||||
enum _button_state {
|
||||
BUTTON_STATE_RELEASED,
|
||||
BUTTON_STATE_PRESSED,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
DWORD buttons;
|
||||
int x;
|
||||
int y;
|
||||
} MOUSE_INFO;
|
||||
struct _random_event {
|
||||
int type;
|
||||
};
|
||||
|
||||
static MOUSE_INFO mouse_info;
|
||||
static struct _event_state_machine {
|
||||
const char* name;
|
||||
} event_state_machines [] = {
|
||||
{ "mouse", },
|
||||
{ "keyboard", },
|
||||
{ "joystick", },
|
||||
{ "button", },
|
||||
{ "single_touch", },
|
||||
{ "multi_touch", },
|
||||
{ "gesture", },
|
||||
{ "tablet_tool", },
|
||||
{ "tablet_pad", },
|
||||
{ "switch", },
|
||||
};
|
||||
|
||||
/************************ Low Level Input Operations **********************/
|
||||
/*
|
||||
* Mouse operations -- Event
|
||||
*/
|
||||
static int mouse_update (void)
|
||||
struct _random_input_contxt {
|
||||
FILE* log_fp;
|
||||
int min_x, max_x, min_y, max_y;
|
||||
int mouse_x, mouse_y, mouse_button;
|
||||
int nr_keys, last_keycode;
|
||||
char* kbd_state;
|
||||
struct _event_state_machine *esm [TABLESIZE(event_state_machines)];
|
||||
};
|
||||
|
||||
static struct _random_input_contxt my_ctxt;
|
||||
|
||||
static void mouse_setrange (int newminx, int newminy, int newmaxx, int newmaxy)
|
||||
{
|
||||
my_ctxt.min_x = newminx;
|
||||
my_ctxt.max_x = newmaxx;
|
||||
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;
|
||||
}
|
||||
|
||||
static void mouse_setxy (int newx, int newy)
|
||||
{
|
||||
if (newx < my_ctxt.min_x)
|
||||
newx = my_ctxt.min_x;
|
||||
if (newx > my_ctxt.max_x)
|
||||
newx = my_ctxt.max_x;
|
||||
if (newy < my_ctxt.min_y)
|
||||
newy = my_ctxt.min_y;
|
||||
if (newy > my_ctxt.max_y)
|
||||
newy = my_ctxt.max_y;
|
||||
|
||||
if (newx == my_ctxt.mouse_x && newy == my_ctxt.mouse_y)
|
||||
return;
|
||||
|
||||
my_ctxt.mouse_x = newx;
|
||||
my_ctxt.mouse_x = newy;
|
||||
}
|
||||
|
||||
static int mouse_update(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void mouse_getxy (int *x, int* y)
|
||||
static void mouse_getxy (int* x, int* y)
|
||||
{
|
||||
*x = mouse_info.x;
|
||||
*y = mouse_info.y;
|
||||
*x = my_ctxt.mouse_x;
|
||||
*y = my_ctxt.mouse_y;
|
||||
}
|
||||
|
||||
static int mouse_getbutton (void)
|
||||
static int mouse_getbutton(void)
|
||||
{
|
||||
return mouse_info.buttons;
|
||||
return my_ctxt.mouse_button;
|
||||
}
|
||||
|
||||
static int keyboard_update (void)
|
||||
static int keyboard_update(void)
|
||||
{
|
||||
return NR_KEYS;
|
||||
if (my_ctxt.last_keycode == 0)
|
||||
return 0;
|
||||
|
||||
return my_ctxt.last_keycode + 1;
|
||||
}
|
||||
|
||||
static const char* keyboard_getstate (void)
|
||||
static const char* keyboard_getstate(void)
|
||||
{
|
||||
return (const char*) kbd_state;
|
||||
return my_ctxt.kbd_state;
|
||||
}
|
||||
|
||||
#define EVENT_TYPE_LD 0
|
||||
#define EVENT_TYPE_LU 1
|
||||
|
||||
#define EVENT_TYPE_RD 2
|
||||
#define EVENT_TYPE_RU 3
|
||||
|
||||
#define EVENT_TYPE_MOVE 4
|
||||
|
||||
#define EVENT_TYPE_KD 5
|
||||
#define EVENT_TYPE_KU 6
|
||||
|
||||
static int event_types_kbd [] =
|
||||
{2, EVENT_TYPE_KD, EVENT_TYPE_KU};
|
||||
static int event_types_pen [] =
|
||||
{3, EVENT_TYPE_LD, EVENT_TYPE_LU, EVENT_TYPE_MOVE};
|
||||
static int event_types_mice [] =
|
||||
{5, EVENT_TYPE_LD, EVENT_TYPE_LU, EVENT_TYPE_RD, EVENT_TYPE_RU, EVENT_TYPE_MOVE};
|
||||
static int event_types_pen_kbd [] =
|
||||
{5, EVENT_TYPE_LD, EVENT_TYPE_LU, EVENT_TYPE_MOVE, EVENT_TYPE_KD, EVENT_TYPE_KU};
|
||||
static int event_types_mice_kbd [] =
|
||||
{7, EVENT_TYPE_LD, EVENT_TYPE_LU, EVENT_TYPE_RD, EVENT_TYPE_RU, EVENT_TYPE_MOVE, EVENT_TYPE_KD, EVENT_TYPE_KU};
|
||||
|
||||
/* defined by mtype */
|
||||
static int* event_types;
|
||||
|
||||
static int event_generator (void)
|
||||
#if 0
|
||||
static void normalize_mouse_pos(int* new_x, int* new_y)
|
||||
{
|
||||
int event_type;
|
||||
int retvalue;
|
||||
static int last_down_key;
|
||||
|
||||
while (1) {
|
||||
|
||||
retvalue = 0;
|
||||
event_type = event_types [(rand () >> 8) % event_types [0] + 1];
|
||||
|
||||
if (event_type == EVENT_TYPE_LD) {
|
||||
if (mouse_info.buttons & IAL_MOUSE_LEFTBUTTON)
|
||||
continue;
|
||||
mouse_info.buttons |= IAL_MOUSE_LEFTBUTTON;
|
||||
retvalue = IAL_MOUSEEVENT;
|
||||
}
|
||||
else if (event_type == EVENT_TYPE_LU) {
|
||||
if (!(mouse_info.buttons & IAL_MOUSE_LEFTBUTTON))
|
||||
continue;
|
||||
mouse_info.buttons &= ~IAL_MOUSE_LEFTBUTTON;
|
||||
retvalue = IAL_MOUSEEVENT;
|
||||
}
|
||||
else if (event_type == EVENT_TYPE_RD) {
|
||||
if (mouse_info.buttons & IAL_MOUSE_RIGHTBUTTON)
|
||||
continue;
|
||||
mouse_info.buttons |= IAL_MOUSE_RIGHTBUTTON;
|
||||
retvalue = IAL_MOUSEEVENT;
|
||||
}
|
||||
else if (event_type == EVENT_TYPE_RU) {
|
||||
if (!(mouse_info.buttons & IAL_MOUSE_RIGHTBUTTON))
|
||||
continue;
|
||||
mouse_info.buttons &= ~IAL_MOUSE_RIGHTBUTTON;
|
||||
retvalue = IAL_MOUSEEVENT;
|
||||
}
|
||||
else if (event_type == EVENT_TYPE_MOVE) {
|
||||
mouse_info.x = (rand () >> 8) % g_rcScr.right;
|
||||
mouse_info.y = (rand () >> 8) % g_rcScr.bottom;
|
||||
retvalue = IAL_MOUSEEVENT;
|
||||
}
|
||||
else if (event_type == EVENT_TYPE_KD) {
|
||||
int key = ((rand () >> 8) % (NR_KEYS - 1)) + 1;
|
||||
|
||||
if (kbd_state [key]) {
|
||||
if (rand () & 0xFFFFF000) {
|
||||
kbd_state [key] = 0;
|
||||
retvalue = IAL_KEYEVENT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
kbd_state [key] = 1;
|
||||
last_down_key = key;
|
||||
retvalue = IAL_KEYEVENT;
|
||||
}
|
||||
}
|
||||
else if (event_type == EVENT_TYPE_KU) {
|
||||
if (last_down_key && kbd_state [last_down_key]) {
|
||||
kbd_state [last_down_key] = 0;
|
||||
last_down_key = 0;
|
||||
retvalue = IAL_KEYEVENT;
|
||||
}
|
||||
}
|
||||
|
||||
if (retvalue)
|
||||
break;
|
||||
}
|
||||
|
||||
return retvalue;
|
||||
if (*new_x < my_ctxt.min_x)
|
||||
*new_x = my_ctxt.min_x;
|
||||
if (*new_x > my_ctxt.max_x)
|
||||
*new_x = my_ctxt.max_x;
|
||||
if (*new_y < my_ctxt.min_y)
|
||||
*new_y = my_ctxt.min_y;
|
||||
if (*new_y > my_ctxt.max_y)
|
||||
*new_y = my_ctxt.max_y;
|
||||
}
|
||||
|
||||
static int wait_event (int which, int maxfd, fd_set *in, fd_set *out, fd_set *except,
|
||||
struct timeval *timeout)
|
||||
static BOOL on_mouse_moved (double dx, double dy)
|
||||
{
|
||||
#ifdef _MGRM_THREADS
|
||||
__mg_os_time_delay (10);
|
||||
int new_x = (int)(my_ctxt.mouse_x + dx + 0.5);
|
||||
int new_y = (int)(my_ctxt.mouse_y + dy + 0.5);
|
||||
|
||||
_DBG_PRINTF("%s: new mouse position: %d, %d (old: %d, %d; delta: %f, %f)\n",
|
||||
__FUNCTION__, new_x, new_y, my_ctxt.mouse_x, my_ctxt.mouse_y, dx, dy);
|
||||
|
||||
normalize_mouse_pos(&new_x, &new_y);
|
||||
if (new_x == my_ctxt.mouse_x && new_y == my_ctxt.mouse_y)
|
||||
return FALSE;
|
||||
|
||||
my_ctxt.mouse_x = new_x;
|
||||
my_ctxt.mouse_y = new_y;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL on_new_mouse_pos (double x, double y)
|
||||
{
|
||||
int new_x = (int)(x + 0.5);
|
||||
int new_y = (int)(y + 0.5);
|
||||
|
||||
_DBG_PRINTF("%s: new mouse position: %d, %d (old: %d, %d)\n",
|
||||
__FUNCTION__, new_x, new_y, my_ctxt.mouse_x, my_ctxt.mouse_y);
|
||||
|
||||
normalize_mouse_pos(&new_x, &new_y);
|
||||
if (new_x == my_ctxt.mouse_x && new_y == my_ctxt.mouse_y)
|
||||
return FALSE;
|
||||
|
||||
my_ctxt.mouse_x = new_x;
|
||||
my_ctxt.mouse_y = new_y;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include <linux/input-event-codes.h>
|
||||
#else
|
||||
int e;
|
||||
|
||||
__mg_os_time_delay (10);
|
||||
e = select (maxfd + 1, in, out, except, timeout);
|
||||
if (e < 0) {
|
||||
/* zero all fd sets */
|
||||
if (in) FD_ZERO (in);
|
||||
if (out) FD_ZERO (out);
|
||||
if (except) FD_ZERO (except);
|
||||
}
|
||||
/* copied from linux/input-event-codes.h */
|
||||
#define BTN_LEFT 0x110
|
||||
#define BTN_RIGHT 0x111
|
||||
#define BTN_MIDDLE 0x112
|
||||
#endif
|
||||
|
||||
return event_generator ();
|
||||
static BOOL on_mouse_button_changed (uint32_t button,
|
||||
enum _button_state state)
|
||||
{
|
||||
int old_mouse_button = my_ctxt.mouse_button;
|
||||
|
||||
switch (button) {
|
||||
case BTN_LEFT:
|
||||
if (state == BUTTON_STATE_RELEASED)
|
||||
my_ctxt.mouse_button &= ~IAL_MOUSE_LEFTBUTTON;
|
||||
else
|
||||
my_ctxt.mouse_button |= IAL_MOUSE_LEFTBUTTON;
|
||||
break;
|
||||
|
||||
case BTN_RIGHT:
|
||||
if (state == BUTTON_STATE_RELEASED)
|
||||
my_ctxt.mouse_button &= ~IAL_MOUSE_RIGHTBUTTON;
|
||||
else
|
||||
my_ctxt.mouse_button |= IAL_MOUSE_RIGHTBUTTON;
|
||||
break;
|
||||
|
||||
case BTN_MIDDLE:
|
||||
if (state == BUTTON_STATE_RELEASED)
|
||||
my_ctxt.mouse_button &= ~IAL_MOUSE_MIDDLEBUTTON;
|
||||
else
|
||||
my_ctxt.mouse_button |= IAL_MOUSE_MIDDLEBUTTON;
|
||||
break;
|
||||
|
||||
default:
|
||||
// not a standard mouse button.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_DBG_PRINTF("%s: new mouse button: 0x%x (old: 0x%x)\n",
|
||||
__FUNCTION__, my_ctxt.mouse_button, old_mouse_button);
|
||||
if (old_mouse_button == my_ctxt.mouse_button)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct _random_event* get_random_event(struct _random_input_contxt* ctxt)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int wait_event_ex (int maxfd, fd_set *in, fd_set *out, fd_set *except,
|
||||
struct timeval *timeout, EXTRA_INPUT_EVENT* extra)
|
||||
{
|
||||
struct _random_event *event;
|
||||
int retval;
|
||||
|
||||
event = get_random_event(&my_ctxt);
|
||||
if (event == NULL) {
|
||||
retval = select (maxfd + 1, in, out, except, timeout);
|
||||
if (retval >= 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LEN_EVENT_TYPES 127
|
||||
|
||||
BOOL InitRandomInput (INPUT* input, const char* mdev, const char* mtype)
|
||||
{
|
||||
char logfile[MAX_PATH + 1];
|
||||
char eventtypes[LEN_EVENT_TYPES + 1];
|
||||
int i, n;
|
||||
|
||||
if (GetMgEtcValue ("random", "logfile", logfile, MAX_PATH) == ETC_OK) {
|
||||
my_ctxt.log_fp = fopen(logfile, "a");
|
||||
if (my_ctxt.log_fp == NULL) {
|
||||
_WRN_PRINTF("Failed to open file %s for logging; log disabled",
|
||||
logfile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
_WRN_PRINTF("No log file defined; log disabled");
|
||||
}
|
||||
|
||||
if (GetMgEtcIntValue ("random", "maxkeycode", &my_ctxt.nr_keys) < 0 ||
|
||||
my_ctxt.nr_keys <= 0) {
|
||||
_WRN_PRINTF("Bad ETC key value: random.maxkeycode; use default: %d",
|
||||
NR_KEYS);
|
||||
my_ctxt.nr_keys = NR_KEYS;
|
||||
}
|
||||
|
||||
my_ctxt.kbd_state = calloc(my_ctxt.nr_keys, sizeof(char));
|
||||
if (my_ctxt.kbd_state == NULL) {
|
||||
_ERR_PRINTF("IAL>RANDOM: failed to allocate space for key state\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (GetMgEtcValue ("random", "eventtypes", eventtypes, LEN_EVENT_TYPES) < 0) {
|
||||
_WRN_PRINTF("Bad ETC key value: random.eventtypes; use default: %s",
|
||||
"mouse");
|
||||
strcpy(eventtypes, "mouse");
|
||||
}
|
||||
|
||||
n = 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++;
|
||||
}
|
||||
}
|
||||
|
||||
input->update_mouse = mouse_update;
|
||||
input->get_mouse_xy = mouse_getxy;
|
||||
input->set_mouse_xy = NULL;
|
||||
input->set_mouse_xy = mouse_setxy;
|
||||
input->get_mouse_button = mouse_getbutton;
|
||||
input->set_mouse_range = NULL;
|
||||
input->set_mouse_range = mouse_setrange;
|
||||
input->suspend_mouse= NULL;
|
||||
input->resume_mouse = NULL;
|
||||
|
||||
@@ -255,20 +370,7 @@ BOOL InitRandomInput (INPUT* input, const char* mdev, const char* mtype)
|
||||
input->suspend_keyboard = NULL;
|
||||
input->resume_keyboard = NULL;
|
||||
input->set_leds = NULL;
|
||||
|
||||
input->wait_event = wait_event;
|
||||
|
||||
event_types = event_types_mice_kbd;
|
||||
if (mtype) {
|
||||
if (strcmp (mtype, "mice") == 0)
|
||||
event_types = event_types_mice;
|
||||
else if (strcmp (mtype, "pen") == 0)
|
||||
event_types = event_types_pen;
|
||||
else if (strcmp (mtype, "pen-kbd") == 0)
|
||||
event_types = event_types_pen_kbd;
|
||||
else if (strcmp (mtype, "kbd") == 0)
|
||||
event_types = event_types_kbd;
|
||||
}
|
||||
input->wait_event_ex = wait_event_ex;
|
||||
|
||||
srand (__mg_os_get_random_seed ());
|
||||
return TRUE;
|
||||
@@ -276,6 +378,10 @@ BOOL InitRandomInput (INPUT* input, const char* mdev, const char* mtype)
|
||||
|
||||
void TermRandomInput (void)
|
||||
{
|
||||
if (my_ctxt.log_fp)
|
||||
fclose(my_ctxt.log_fp);
|
||||
if (my_ctxt.kbd_state)
|
||||
free(my_ctxt.kbd_state);
|
||||
}
|
||||
|
||||
#endif /* _MGIAL_RANDOM */
|
||||
|
||||
Reference in New Issue
Block a user