📄 event.c
字号:
/******************************************************** * EGui code,LGPL * Function : Egui input event and windows manage * Author: asmcos@hotmail.com * Data : 2006-03-03 * $Id: event.c,v 1.17 2006/04/14 00:53:28 hjs Exp $ ********************************************************/#include "kegui.h"#include <linux/timer.h>typedef struct _event_queue { int head; int tail; int count; EGui_Event events[EVENT_MAX]; } event_queue;#define ACC_MAX 3struct move_event { int move_true; int acc_count; int pid ;};#define WAIT_TIME (HZ/100) /* 10msec */struct move_event move_event;static int oldpid = -1; // cursor pid switchunsigned long timeout ;EGui_Event newevent;event_queue current_event, *p_current_event = ¤t_event;int hide_cursor_event (int pid);void event_init(void){ /* init the header */ p_current_event -> head = 0; p_current_event -> tail = 0; p_current_event -> count = 0; move_event.move_true = 0 ; move_event.pid = 0; timeout = jiffies; return ;}/* return * 1 is empty * 0 isn't empty */int queue_is_empty(event_queue *q){ return (q->count == 0);}/* return * 1 is full * 0 isn't full */int queue_is_full(event_queue *q){ return (q->count == EVENT_MAX);}void queue_add(event_queue *q, EGui_Event * new_event){ if (queue_is_full(q)) { return; } q->events [q->tail] = *new_event; q->tail = (q->tail+1) % EVENT_MAX; q->count ++;}EGui_Event * queue_del(event_queue *q,int pid){ struct task_struct *p; int save_head = q->head; if (queue_is_empty(q)) { return NULL; } /* Only get match event. */ if (q->events[save_head].pid != pid) { /* check task exist */ p = find_task_by_pid (pid); if (p==NULL) { /* the event's pid die */ q->head = (q->head+1) % EVENT_MAX; q->count --; return NULL; } return NULL; } q->head = (q->head+1) % EVENT_MAX; q->count --; return &(q->events[save_head]);}/* * Event handler * */int get_event (void __user * argp){ EGui_Event *event; window_list *list; int retval = 0; list = find_list_by_pid (current->pid); event = queue_del (p_current_event,list->pid); if (event == NULL) { /* need modify,kernel will remove it. */ list->done = 0; retval = wait_event_interruptible_timeout(list->event_wait,list->done,1); list->done = 1; if (!retval) return -1; event = queue_del (p_current_event,list->pid); if (event == NULL) return -1; } if (event->type == CURSOR_MOVE) while ((timeout + WAIT_TIME) > jiffies ); return copy_to_user(argp,event,sizeof(EGui_Event));}int report_move (void __user * argp){ move_event.move_true = 1; move_event.pid = current->pid; move_event.acc_count = 0; return 0;}/* return * 1: don't accumulate, send move event * 0: wait accumulate. */int accumulate_event (void){ /* We accumulate ACC_MAX times window move events. */ if (move_event.acc_count <ACC_MAX) { move_event.acc_count++; return 1; } move_event.acc_count = 0; return 0;}int report_event (void __user * argp){ window_list *list; EGui_Window *window = ( EGui_Window * )argp; list = find_list_by_pid (current->pid); memset(list->width_in,0,max_width); memset(list->height_in,0,max_height); /* set inside is 1 */ memset(list->width_in + window->x,1,window->width); memset(list->height_in + window->y,1,window->height); return 0;}intwake_event (window_list * list){ struct task_struct *p; newevent.pid = list->pid; /* hide old window's cursor */ if ((oldpid != list->pid) && (newevent.type == CURSOR_MOVE)) { hide_cursor_event (oldpid); } switch (newevent.type) { case CURSOR_MOVE: oldpid = list->pid; break; case W_MOVE: /*accumulate window move event */ if (accumulate_event ()) return 1; break; default: break; } queue_add(p_current_event,&newevent); if (list->done == 0) { /* check task exist */ p = find_task_by_pid (list->pid); if (p==NULL) { return -1; } wake_up_interruptible(&list->event_wait); } return 0;}/* when cursor move between two windows. * We need close old window's cursor. * */inthide_cursor_event (int pid){ window_list * list = NULL; struct task_struct *p; EGui_Event event; list = find_list_by_pid (pid); if (list == 0) { return -1; } event.pid = list->pid; event.type = HIDE_CURSOR; timeout = jiffies; queue_add(p_current_event,&event); if (list->done == 0) { list->done = 1; /* check task exist */ p = find_task_by_pid (list->pid); if (p==NULL) { return -1; } wake_up_interruptible(&list->event_wait); } return 0; }/************************* *input event handler * * **************************/intsend_mouseinfo (unsigned int code,int value){ switch (code) { case REL_X: cursor_x += value; if ( cursor_x <0) cursor_x = 0; if (cursor_x > max_width) cursor_x = max_width; break; case REL_Y: cursor_y += value; if ( cursor_y <0) cursor_y = 0; if (cursor_y > max_height) cursor_y = max_height; break; default: return 1; } newevent.type = CURSOR_MOVE;; newevent.x = cursor_x; newevent.y = cursor_y; newevent.code = code; if (move_event.move_true == 1) newevent.type = W_MOVE; return 0;}intsend_keyinfo (unsigned int code,int value){ switch (code) { case BTN_LEFT: if (value == 1) { newevent.type = CLICK_LEFT; } if (value == 0) { newevent.type = REL_LEFT; move_event.move_true = 0; move_event.pid = 0; } break; case KEY_ESC...KEY_COMPOSE: /* 1- 127 */ if (value == 1) { newevent.type = PRESS_KEY; } if (value == 0) { newevent.type = RELEASE_KEY; } newevent.code = code; break; default: return 1; } return 0;}/*********************************** * type : keyboard,mouse * code : key code, x,y * value : x-size,y-size ***********************************/integui_event (unsigned int type,unsigned int code, int value){ window_list * list = NULL; int ret = 0; switch (type) { case EV_SYN: return 0; case EV_REL: ret = send_mouseinfo (code,value); break; case EV_KEY: ret = send_keyinfo (code,value); break; default: break; } if (ret) return ret; if (newevent.type == W_MOVE) { /* *if need move window, * maybe mouse event is outside of window. * so we find list by pid only. */ list = find_list_by_pid (move_event.pid); } else { list = find_list_by_xy (cursor_x,cursor_y); } /* Not found window in window_list*/ if (list == 0) { return -1; } wake_event (list); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -