int main(void) { struct event_listener server_listener; struct egui_uds server_uds; if(0 != uds_init(&server_uds, SOCK_STREAM, SERVER_PATH, PEER_ROLE_SERVER)) { EGUI_PRINT_ERROR("Failed to init server uds"); return -1; } event_listener_init(&server_listener); event_listener_add_read_event(&server_listener, &server_uds, &server_listener, server_accept_handler, NULL); if(0 != event_listener_exec(&server_listener)) { EGUI_PRINT_ERROR("failed to execute event_listener"); return -1; } event_listener_exit(&server_listener); if(0 != uds_exit(&server_uds)) { EGUI_PRINT_ERROR("failed to exit server uds"); return -1; } return 0; }
si_t save_as_button_callback(void* btn, void* msg) { union message* m = (union message*)msg; struct button* b = NULL; switch(m->base.type) { case MESSAGE_TYPE_MOUSE_SINGLE_CLICK: if(NULL == save_window) { save_window = window_init("save window"); /* 申请失败 */ if(NULL == main_window) { EGUI_PRINT_ERROR("failed to init save window"); application_exit(); return -1; } window_set_bounds(save_window, main_window->area.x + 30, main_window->area.y + 30, 300, 60); window_set_color(save_window, NULL, &barely_blue); save_text_line = text_line_init(FILE_MAX, 0); if(NULL == save_text_line) { EGUI_PRINT_ERROR("failed to init save_text_line on save window"); application_exit(); return -1; } text_line_set_bounds(save_text_line, 5, 5, 230, 50); text_line_set_placeholder(save_text_line, "input file name"); text_line_set_color(save_text_line, &dark_blue, NULL, &light_green); b = button_init("ok"); if(NULL == b) { EGUI_PRINT_ERROR("failed to init ok button on save window"); application_exit(); return -1; } button_set_bounds(b, 240, 10, 50, 40); button_set_color(b, &dark_blue, &light_green); button_set_font(b, FONT_MATRIX_12); b->callback = save_window_ok_button_callback; object_attach_child(OBJECT_POINTER(save_window), OBJECT_POINTER(b)); object_attach_child(OBJECT_POINTER(save_window), OBJECT_POINTER(save_text_line)); application_add_window(NULL, save_window); break; } else { EGUI_PRINT_ERROR("save window already open!"); } default: button_default_callback(btn, msg); } return 0; }
/** * parse each widget * * @param w: pointer to widget * @param m: no use * @return: NULL **/ static struct widget* do_parse_widget(struct widget* w, union message* m) { NOT_USED(m); /** * record focusable widget **/ if(w->input_enable == 1) { list_push_back(&global_application.focus_list, &w, sizeof(w)); } /** * register window and update active window **/ if(w->is_window) { struct window* parent = (struct window*)object_parent(OBJECT_POINTER(w)); struct window* window_ptr = WINDOW_POINTER(w); si_t parent_descriptor = (parent == NULL ? 0 : parent->descriptor); si_t window_descriptor = register_window(parent_descriptor, window_ptr->title, window_ptr->area.x, window_ptr->area.y, window_ptr->area.width, window_ptr->area.height, window_ptr->minimize_enable, window_ptr->maximize_enable, window_ptr->modal); if(0 == window_descriptor) { EGUI_PRINT_ERROR("failed to register window %s", window_ptr->title); return NULL; } window_ptr->descriptor = window_descriptor; global_application.focus = window_ptr; /** * find icon for the application **/ if((window_ptr->icon_path = (char*)malloc(256)) == NULL) { EGUI_PRINT_ERROR("failed to register window"); return NULL; } else { /** * in C89 standard, snprintf() is NOT included in <stdio.h> * so you have to use sprintf, which may be dangerous. be careful **/ sprintf(window_ptr->icon_path, "%s/icons/%s.bmp", global_application.icon_root_path, global_application.name); if(access(window_ptr->icon_path, R_OK) == -1) { sprintf(window_ptr->icon_path, "%s/icons/default.bmp", global_application.icon_root_path); } } } return NULL; }
/** * 对标准输入的写操作将触发的回调函数 * 即event_listener_add_write_handler()中标准输入的通信句柄所对应的处理函数 * * 读取命令,调用对应函数发送请求 * 1. $0 draw_line x1 y1 x2 y2 * 2. $0 register_window fd title * 3. $0 window_manager_exit **/ si_t command_handler(struct egui_uds* uds_ptr, addr_t arg) { char command_buf[1024]; struct egui_uds* server_uds_ptr = (struct egui_uds*)arg; const char draw_line_command[] = "draw_line"; const char register_window_command[] = "register_window"; const char window_manager_exit_command[] = "window_manager_exit"; NOT_USED(uds_ptr); EGUI_PRINT_INFO("callback command_handler() is called"); scanf("%s", command_buf); if(0 == strncmp(command_buf, draw_line_command, sizeof(draw_line_command))) { si_t x1 = 0, y1 = 0, x2 = 0, y2 = 0; EGUI_PRINT_INFO("get draw_line_command"); scanf("%d%d%d%d", (int*)&x1, (int*)&y1, (int*)&x2, (int*)&y2); if(0 != fake_draw_line(server_uds_ptr, x1, y1, x2, y2)) { EGUI_PRINT_ERROR("failed to execute draw line command"); } } else if(0 == strncmp(command_buf, register_window_command, sizeof(register_window_command))) { si_t fd = 0; char title_buf[1024] = {0}; EGUI_PRINT_INFO("get register_window_command"); scanf("%d%s", (int*)&fd, title_buf); if(0 != fake_register_window(server_uds_ptr, fd, title_buf)) { EGUI_PRINT_ERROR("failed to execute register window command"); } } else if(0 == strncmp(command_buf, window_manager_exit_command, sizeof(window_manager_exit_command))) { EGUI_PRINT_INFO("get window_manager_exit_command"); if(0 != fake_window_manager_exit(server_uds_ptr)) { EGUI_PRINT_ERROR("failed to execute window manager exit command"); } /** 如果用户输入退出窗口管理器的命令,那么客户端的程序也应当退出 **/ return SELECTER_RETURN_TYPE_END; } else { EGUI_PRINT_ERROR("unknow command %s", command_buf); EGUI_PRINT_INFO(help_str); } return SELECTER_RETURN_TYPE_CONTINUE; }
si_t application_exec() { /** * parse the application before execute **/ application_parse(); event_listener_add_read_event(&global_application.app_event_listener, &global_application.uds, NULL, application_event_handler, NULL); while(!queue_empty(&global_application.message_queue)) { union message* msg = queue_front(&global_application.message_queue); application_handle_message(msg); queue_pop(&global_application.message_queue); } global_application.exec_flag = 1; if(0 != event_listener_exec(&global_application.app_event_listener)) { EGUI_PRINT_ERROR("failed to run event_listener."); return -1; } global_application.exec_flag = 0; return 0; }
si_t application_event_handler(struct egui_uds* uds_ptr, addr_t arg) { union message msg; if(0 != comm_recv_msg(uds_ptr, &msg)) { EGUI_PRINT_ERROR("failed to recv msg"); return SELECTER_RETURN_TYPE_CONTINUE; } application_handle_message(&msg); /** * 处理器消息过程中,应用程序需要发送一些请求,等待回应的过程中,窗口管理器可能会发送消息。 * 因此当请求处理完毕之后,再逐一处理消息。 **/ while(!queue_empty(&global_application.message_queue)) { union message* msg = queue_front(&global_application.message_queue); application_handle_message(msg); queue_pop(&global_application.message_queue); } return SELECTER_RETURN_TYPE_CONTINUE; }
/** * @brief 初始化窗口管理器图形相关 * * @param framebuffer_path framebuffer设备路径 * @param top_margin 配置项 屏幕上方留白的像素 * @param down_margin 配置项 屏幕下方留白的像素 * @param left_margin 配置项 屏幕左方留白的像素 * @param right_margin 配置项 屏幕右方留白的像素 * * @return 成功返回0 否则返回-1 **/ static si_t graph_init(char* framebuffer_path, si_t top_margin, si_t down_margin, si_t left_margin, si_t right_margin) { struct graphics_device* gd_ptr = NULL; /* 初始化屏幕 */ screen_init(framebuffer_path); /* 设置颜色的限制 */ screen_color_limit(); /** * 初始化窗口管理器的图形设备 **/ global_wm.gd_handler = engine_graphics_device_init(0, 0, global_screen.width, global_screen.height, 0,0,0,0,0); if(0 == global_wm.gd_handler) { EGUI_PRINT_ERROR("failed to init window manager graph device."); return -1; } gd_ptr = (struct graphics_device*)global_wm.gd_handler; gd_ptr->screen.memory_addr = global_screen.memory_addr; gd_ptr->screen.buffer_addr = NULL; gd_ptr->screen.video_access_mode = VIDEO_ACCESS_MODE_DIRECT; /** * 初始化窗口区域 **/ rectangle_set(&global_wm.work_area, 0 + left_margin, 0 + top_margin, global_screen.width - left_margin - right_margin, global_screen.height - top_margin - down_margin); /** 绘制桌面 **/ engine_set_color(global_wm.gd_handler, global_wm.backcolor.r, global_wm.backcolor.g, global_wm.backcolor.b, global_wm.backcolor.a); engine_fill_rectangle(global_wm.gd_handler, global_wm.work_area.x, global_wm.work_area.y, global_wm.work_area.width, global_wm.work_area.height); return 0; }
/** * 客户端请求处理函数:这个函数是selector里面的客户端的通信句柄对应的回调函数 **/ si_t client_request_handler(struct egui_uds* uds_ptr, addr_t arg) { struct queue message_queue; si_t ret = 0; NOT_USED(arg); EGUI_PRINT_INFO("callback client_request_handler() is called"); queue_init(&message_queue); /** 接受request回应respond **/ ret = comm_recv_request_and_send_respond(uds_ptr, &message_queue, request_handler); if(EXIT_NUMBER == ret) { return SELECTER_RETURN_TYPE_END; } /** 发送相关消息 **/ while(!queue_empty(&message_queue)) { union message* message_ptr = (union message*)queue_front(&message_queue); if(0 != comm_send_message(uds_ptr, message_ptr)) { EGUI_PRINT_ERROR("failed to send message!"); } queue_pop(&message_queue); } queue_exit(&message_queue); return SELECTER_RETURN_TYPE_CONTINUE; }
/** * 发送window_manager_exit请求 **/ int fake_window_manager_exit(struct egui_uds* uds_ptr) { si_t ret = 0; if(0 != comm_send_request(uds_ptr, REQUEST_TYPE_WINDOW_MANAGER_QUIT, NULL, 0)) { EGUI_PRINT_ERROR("failed to send window manager exit request"); return -1; } if(0 != comm_recv_respond(uds_ptr, RESPOND_TYPE_WINDOW_MANAGER_QUIT, &ret, NULL)) { EGUI_PRINT_ERROR("failed to recv window manager exit respond"); return -1; } EGUI_PRINT_INFO("send window manager exit request, recv ret %d", (int)ret); return ret; }
static si_t send_request_and_malloc_for_respond(si_t request_type, si_t respond_type, const_addr_t body, ui_t body_size, addr_t* result) { if(0 != comm_send_request(lib_uds, request_type, body, body_size)) { EGUI_PRINT_ERROR("failed to send request[%s]", request_type_to_str(request_type)); return -1; } if(0 != comm_recv_respond_in_new_buffer(lib_uds, respond_type, result, message_queue)) { EGUI_PRINT_ERROR("failed to receive respond[%s]", respond_type_to_str(respond_type)); return -1; } return 0; }
void window_manager_input_destructor(struct egui_uds* uds, addr_t arg) { struct input_device* id_ptr = arg; NOT_USED(uds); if(0 != id_ptr->input_exit(id_ptr)) { EGUI_PRINT_ERROR("failed to exit input device"); } }
/** * 发送带有附加内容的负载,读取返回的retval。如果发送或接受过程出错或malloc失败返回-1,否则返回回应包的retval * * @param request_type 请求类型 * @param respond_type 回应类型 * @param body 标准负载指针 * @param body_len 标准负载的长度 * @param extra_context 附加内容指针 * @param extra_context_len 附加内容长度 **/ static si_t send_body_with_extra_context_and_return_respond(si_t request_type, si_t respond_type, const_addr_t body , ui_t body_len, const_addr_t extra_context, ui_t extra_context_len) { si_t result = 0; if(0 != comm_send_request_with_extra(lib_uds, request_type, body, body_len, extra_context, extra_context_len)) { EGUI_PRINT_ERROR("failed to send request[%s] with extra content", request_type_to_str(request_type)); return -1; } if(0 != comm_recv_respond(lib_uds, respond_type, &result, message_queue)) { EGUI_PRINT_ERROR("failed to receive respond[%s]", respond_type_to_str(respond_type)); return -1; } return result; }
/** * 发送draw line请求 **/ int fake_draw_line(struct egui_uds* uds_ptr, si_t x1, si_t y1, si_t x2, si_t y2) { struct packet_body_draw_line body; si_t ret = 0; request_set_draw_line(&body, 0, x1, y1, x2, y2); if(0 != comm_send_request(uds_ptr, REQUEST_TYPE_DRAW_LINE, &body, sizeof(body))) { EGUI_PRINT_ERROR("failed to send draw line request"); return -1; } if(0 != comm_recv_respond(uds_ptr, RESPOND_TYPE_DRAW_LINE, &ret, NULL)) { EGUI_PRINT_ERROR("failed to recv draw line respond"); return -1; } EGUI_PRINT_INFO("send draw line request, recv ret %d", (int)ret); return ret; }
static si_t _event_listener_handler(struct egui_uds* uds_ptr, addr_t app_addr) { si_t ret = comm_recv_request_and_send_respond(uds_ptr, app_addr, _server_lib_handler); if(-1 == ret) { EGUI_PRINT_ERROR("failed to recv request or send respond"); return SELECTER_RETURN_TYPE_CONTINUE; } return ret; }
/** * @brief 输入事件模块初始化 * * @param keybd_device_path 鼠标路径 * @param mouse_device_path 键盘路径 * @param double_click_delay 双击时间间隔 * * @return 成功返回0 否则返回-1 **/ static si_t event_init(char* keybd_device_path, char* mouse_device_path, si_t double_click_delay) { struct input_device device; /** * 初始化输入设备数组 **/ vector_init(&global_wm.input_device_vector); /** * 初始化键盘输入设备 **/ if(keybd_init(&device, keybd_device_path) < 0) { EGUI_PRINT_ERROR("failed to init keybd device"); return -1; } /** * 将键盘输入设备添加到输入设备队列中 **/ vector_push_back(&global_wm.input_device_vector, &device, sizeof(device)); /** * 初始化鼠标输入设备 **/ if(mouse_init(&device, mouse_device_path, double_click_delay) < 0) { EGUI_PRINT_ERROR("failed to init mouse device"); return -1; } /** * 将键盘输入设备添加到输入设备队列中 **/ vector_push_back(&global_wm.input_device_vector, &device, sizeof(device)); /** * 初始化消息队列 **/ list_init(&global_wm.message_list); return 0; }
/** * 发送注册窗口请求 **/ int fake_register_window(struct egui_uds* uds_ptr, si_t parent_fd, char* title) { struct packet_body_register_window body; si_t ret = 0; request_set_register_window(&body, parent_fd, title, strlen(title) + 1, 0, 0, 0, 0, 0, 0, 0); if(0 != comm_send_request_with_extra(uds_ptr, REQUEST_TYPE_REGISTER_WINDOW, &body, sizeof(body), title, strlen(title) + 1)) { EGUI_PRINT_ERROR("failed to send register window request"); return -1; } if(0 != comm_recv_respond(uds_ptr, RESPOND_TYPE_REGISTER_WINDOW, &ret, NULL)) { EGUI_PRINT_ERROR("failed to recv register window respond"); return -1; } EGUI_PRINT_INFO("send register window request, recv ret %d", (int)ret); return 0; }
int main(int argc, char* argv[]) { /** * TODO LOG **/ /** * TODO 命令行参数 **/ #if 0 /** commented by padme 2012-05-12 {{{ **/ if(SIG_ERR == signal(SIGCHLD,SIG_IGN)) { EGUI_PRINT_ERROR("failed to set singal handler for SIGCHLD"); return -1; } if(SIG_ERR == signal(SIGPIPE,SIG_IGN)) { EGUI_PRINT_ERROR("failed to set singal handler for SIGPIPE"); return -1; } #endif /** commented by padme 2012-05-12 }}} **/ if(0 != window_manager_init()) { EGUI_PRINT_ERROR("failed to init window_manager"); return -1; } if(0 != window_manager_run()) { EGUI_PRINT_ERROR("failed to run window_manager"); } window_manager_exit(); return 0; }
/* * @breif 本函数功能是通过判断 * */ si_t shortcut_update_all_areas ( struct shortcut * sh ) { struct rectangle area; /* 总字数 , 单字宽度,单字高度,每行字数 ,总行数,最后一行的字数 */ si_t char_total_num ; si_t font_height; si_t font_width; si_t text_line_num; si_t maxlen; application_widget_absolute_area(WIDGET_POINTER(sh), &area); if(shortcut_get_is_text_visiable(sh) == 1) { /* 总字数 , 单字宽度,单字高度 */ char_total_num = strlen( sh->text ); font_height = get_font_height( sh->gd ) ; font_width = get_font_width( sh->gd ) ; maxlen = area.width * 2 / font_width; text_line_num = char_total_num / maxlen + 1; if( font_height > sh->area.height || font_width >sh->area.width) { EGUI_PRINT_ERROR("font for desktop shortcut is too large"); return -1; } sh->text_field.x = area.x ; sh->text_field.y = area.y + area.height - ( text_line_num * font_height ); sh->text_field.width = area.width; sh->text_field.height = text_line_num * font_height ; sh->img_field.x = area.x ; //sh->img_field.x = area.x + area.width/4 ; sh->img_field.y = area.y ; sh->img_field.width = area.width ; sh->img_field.height = area.height - sh->text_field.height; } else { sh->img_field.x = area.x ; sh->img_field.y = area.y ; sh->img_field.width = area.width ; sh->img_field.height = area.height ; } return 1; }
int main(void) { struct event_listener client_listener; struct egui_uds client_uds; struct egui_uds stdin_uds; event_listener_init(&client_listener); /** * 初始化客户端通信句柄并将其对应的回调函数设置为server_message_handler **/ if(0 != uds_init(&client_uds, SOCK_STREAM, SERVER_PATH, PEER_ROLE_CLIENT)) { EGUI_PRINT_ERROR("Failed to init server uds"); return -1; } event_listener_add_read_event(&client_listener, &client_uds, NULL, server_message_handler, NULL); /** * 初始化标准输入通信句柄并将对应的回调函数设置为command_handler **/ uds_init_from_naked_socket(&stdin_uds, STDIN_FILENO); event_listener_add_read_event(&client_listener, &stdin_uds, &client_uds, command_handler, NULL); /** 打印帮助信息 **/ EGUI_PRINT_INFO(help_str); if(0 != event_listener_exec(&client_listener)) { EGUI_PRINT_ERROR("failed to execute event_listener"); return -1; } event_listener_exit(&client_listener); return 0; }
si_t application_exit() { struct object * addr; si_t i, n; /** * release focus list **/ list_exit(&(global_application.focus_list)); /* 有多少个窗口 */ n = vector_size(&(global_application.window_vector)); /* 依次删除窗口 */ for(i = n - 1; i >= 0; -- i) { addr = vector_at(&(global_application.window_vector), i); /* 这里没有逐个注销窗口类对象或者它的派生类对象。 因为窗口管理程序收到用户应用程序的退出请求后, 会释放关于这个用户应用程序的所有资源。 */ /* 释放这棵树 */ object_tree_free(addr->parent); /* 从窗口向量中删除这个节点 */ vector_erase(&(global_application.window_vector), i); } vector_exit(&(global_application.window_vector)); if(0 != cancel_application()) { EGUI_PRINT_ERROR("failed to cancle application"); } event_listener_exit(&global_application.app_event_listener); queue_exit(&global_application.message_queue); uds_exit(&global_application.uds); free(global_application.name); free(global_application.icon_root_path); term_restore(); return 0; }
/** * 服务器连接处理函数:这个函数是event_listener里面服务器端通信句柄对应的回调函数 * 接受客户端的通信句柄,将其添加到event_listener中 **/ si_t server_accept_handler(struct egui_uds* uds_ptr, addr_t arg) { struct event_listener* server_listener = (struct event_listener*)arg; struct egui_uds new_uds; EGUI_PRINT_INFO("callback server_accept_handler() is called"); if(0 != accept_as_uds(uds_ptr, &new_uds)) { EGUI_PRINT_ERROR("Failed to accept client connection"); return SELECTER_RETURN_TYPE_CONTINUE; } event_listener_add_read_event(server_listener, &new_uds, NULL, client_request_handler, uds_destructor); return SELECTER_RETURN_TYPE_CONTINUE; }
/** * @brief 初始化通信模块 * * @param server_path 配置项 窗口管理器的socket路径 * * @return 成功返回0 否则返回-1 **/ static si_t comm_init(char* server_path) { int i = 0; /** * 初始化窗口管理器的通信句柄 用来接受用户应用程序的连接请求 **/ if(0 != uds_init(&global_wm.uds, SOCK_STREAM, server_path, PEER_ROLE_SERVER)) { EGUI_PRINT_ERROR("Failed to init server uds"); return -1; } /** * 初始化监听事件的event_listener **/ event_listener_init(&global_wm.server_listener); /** * 添加event_listener监听来自窗口管理器通信句柄的读请求 若有读请求发生则调用window_manager_accept_handler处理 * 析构函数为简单关闭通信句柄 **/ event_listener_add_read_event(&global_wm.server_listener, &global_wm.uds, NULL, window_manager_accept_handler, NULL); /** * 设置对来自客户端的请求处理函数 * * 当客户端建立连接后 在window_manager_accept_handler中 将调用server_lib的接口添加一个客户端 * server_lib添加客户端的具体实现是 将这个客户端句柄添加到event_listener里面监听读请求 并使用server_lib内部的事件处理函数 * server_lib内部的事件处理函数 将来自客户端的绘图请求直接调用绘图模块的函数处理 然后将函数返回值发回回应包 * 而来自客户端需要窗口管理器处理的窗口/应用程序管理类的请求 则通过窗口管理器在window_manger_set_request_handler里面设置的处理函数处理 **/ window_manager_set_request_handler(); /** * 设置对来自输入设备的请求处理函数 * 事件处理函数为window_manager_input_handler 析构函数为input_exit对应的函数 **/ for(i = 0; i != vector_size(&global_wm.input_device_vector); ++ i) { struct input_device* device_ptr = vector_at(&global_wm.input_device_vector, i); event_listener_add_read_event(&global_wm.server_listener, &device_ptr->uds, device_ptr, window_manager_input_handler, window_manager_input_destructor); } return 0; }
/** * 对来自服务器的消息的处理函数 * 即event_listener_add_write_handler()中客户端通信句柄对应的处理函数 * * 只处理窗口激活消息 **/ si_t server_message_handler(struct egui_uds* uds_ptr, addr_t arg) { union message msg; NOT_USED(arg); EGUI_PRINT_INFO("callback server_message_handler() is called"); if(0 != comm_recv_msg(uds_ptr, &msg)) { EGUI_PRINT_ERROR("failed to recv message from server"); return SELECTER_RETURN_TYPE_CONTINUE; } switch(message_get_type(&msg)) { case MESSAGE_TYPE_WINDOW_ACTIVATE: EGUI_PRINT_INFO("recieved window activate message!"); break; default: EGUI_PRINT_INFO("recieved unknown message, type = %d", (int)message_get_type(&msg)); break; } return SELECTER_RETURN_TYPE_CONTINUE; }
/** * 初始化窗口管理器 * 就不写注释了 函数名写的已经很明白。。 **/ si_t window_manager_init() { if(0 != terminal_init()) { EGUI_PRINT_ERROR("failed to init terminal"); return -1; } if(0 != config_init()) { EGUI_PRINT_ERROR("failed to init config"); return -1; } if(0 != event_init("/dev/input/event9", "/dev/input/event10", 1000)) { EGUI_PRINT_ERROR("failed to init event module"); return -1; } if(0 != comm_init("/tmp/server")) { EGUI_PRINT_ERROR("failed to init comm module"); return -1; } if(0 != graph_init("/dev/fb0", 0, 0, 0, 0)) { EGUI_PRINT_ERROR("failed to init graph module"); return -1; } if(0 != cursor_init("CURSOR_SHAPE_X")) { EGUI_PRINT_ERROR("failed to init cursor"); return -1; } applications_init(3, 30); return 0; }
si_t window_manager_input_handler(struct egui_uds* uds_ptr, addr_t arg) { struct input_device* input_device_ptr = (struct input_device*)arg; NOT_USED(uds_ptr); if(0 != input_device_ptr->deal_with_input(input_device_ptr, &global_wm.message_list)) { EGUI_PRINT_ERROR("failed to deal with input"); } /* 消息队列非空 */ while(list_empty(&(global_wm.message_list)) == 0) { union message * message; /* 获得第一个消息 */ message = list_front(&(global_wm.message_list)); /* 消息中光标的位置 */ message->base.cursor_position.x = global_wm.old_cursor.x; message->base.cursor_position.y = global_wm.old_cursor.y; /* 有包含窗口的用户应用程序 */ if(global_wm.active_app_info_ptr != NULL && global_wm.active_win_info_ptr != NULL) { send_input_message(&global_wm.active_app_info_ptr->uds, message, (si_t)global_wm.active_win_info_ptr); } if(message->base.type == MESSAGE_TYPE_MOUSE_PRESS) { /** * if not clicked in workspace area, send to desktop thread **/ if(!is_point_in_area(&message->base.cursor_position, &global_wm.work_area) && NULL != global_wm.desktop_app_ptr) { send_input_message(&global_wm.desktop_app_ptr->uds, message, 0); } else { /* 更新活动窗口 */ mask_active_by_mouse_down(message); handle_desktop_press(message); handle_button_press(message); handle_title_bar_press(message); handle_frame_press(message); } } else if(message->base.type == MESSAGE_TYPE_MOUSE_RELEASE) { /** * if not clicked in workspace area, send to desktop thread **/ if(!is_point_in_area(&message->base.cursor_position, &global_wm.work_area)) { send_input_message(&global_wm.desktop_app_ptr->uds, message, 0); } else { handle_desktop_release(message); handle_button_release(message); handle_widget_move(message); handle_widget_resize(message); } } /* 绘制鼠标并且更新光标的坐标 */ else if(message->base.type == MESSAGE_TYPE_MOUSE_MOVE || message->base.type == MESSAGE_TYPE_MOUSE_MOVE_POINT) { if(message->mouse.code == INPUT_CODE_MOUSE_X_OFFSET) { if(message->base.type == MESSAGE_TYPE_MOUSE_MOVE) { global_wm.new_cursor.x = global_wm.new_cursor.x + message->mouse.value; } else { global_wm.new_cursor.x = (double)message->mouse.value/MOUSE_RESOLUTION* global_screen.width; } if(global_wm.new_cursor.x < 0) { global_wm.new_cursor.x = 0; } else if(global_wm.new_cursor.x >= (si_t)global_screen.width) { global_wm.new_cursor.x = global_screen.width - 1; } } else if(message->mouse.code == INPUT_CODE_MOUSE_Y_OFFSET) { if(message->base.type == MESSAGE_TYPE_MOUSE_MOVE) { global_wm.new_cursor.y = global_wm.new_cursor.y + message->mouse.value; } else { global_wm.new_cursor.y = (double)message->mouse.value/MOUSE_RESOLUTION* global_screen.height; } if(global_wm.new_cursor.y < 0) { global_wm.new_cursor.y = 0; } else if(global_wm.new_cursor.y >= (si_t)global_screen.height) { global_wm.new_cursor.y = global_screen.height - 1; } } accumulate_widget_move(message); accumulate_widget_resize(message); cursor_paint(); global_wm.old_cursor = global_wm.new_cursor; } /* 删除已分发的消息 */ list_pop_front(&(global_wm.message_list)); } return 0; }
si_t application_init(si_t video_access_mode, si_t application_type, char* name) { /** * 加载配置项 **/ if(0 != application_load_config()) { EGUI_PRINT_ERROR("failed to load config."); return -1; } /** * 初始化客户端通信句柄 **/ if(0 != uds_init(&global_application.uds, SOCK_STREAM, global_application.server_path, PEER_ROLE_CLIENT)) { EGUI_PRINT_ERROR("Failed to init client uds"); return -1; } /** * 初始化消息队列 **/ queue_init(&global_application.message_queue); client_lib_init(&global_application.uds, &global_application.message_queue); /** * 初始化event_listener **/ event_listener_init(&global_application.app_event_listener); global_application.exec_flag = 0; /** * init focus list **/ list_init(&(global_application.focus_list)); /* 初始化向量 */ vector_init(&(global_application.window_vector)); /** * 应用程序名称 **/ global_application.name = malloc(strlen(name) + 1); if(NULL == global_application.name) { EGUI_PRINT_SYS_ERROR("failed to malloc for application name %s. malloc()", name); return -1; } strncpy(global_application.name, name, strlen(name) + 1); global_application.application_type = application_type; if(0 != register_application(video_access_mode, application_type, name)) { EGUI_PRINT_ERROR("failed to register application %s.", name); return -1; } global_application.focus = NULL; global_application.main_window = NULL; global_application.desktop_ptr = NULL; global_application.desktop_msg_handler = NULL; term_init(); return 0; }
static si_t deal_with_keybd(struct input_device * self, struct list* msg_list) { struct input_event ie; union message msg=(const union message){{0}}; /* 读取数据 */ if(uds_read(&self->uds, &ie, sizeof(struct input_event)) < 0) { EGUI_PRINT_ERROR("failed to read from keybd input device."); return -1; } /* 时间 */ msg.mouse.time.tv_sec = ie.time.tv_sec; msg.mouse.time.tv_usec = ie.time.tv_usec; /** * 只处理按键事件 **/ if(ie.type != EV_KEY) { return 0; } /* 松开键盘的键 */ if(ie.value == 0) { msg.keybd.type = MESSAGE_TYPE_KEYBD_RELEASE; msg.keybd.value = 0; } /* 按下键盘的键 */ else if(ie.value == 1) { msg.keybd.type = MESSAGE_TYPE_KEYBD_PRESS; msg.keybd.value = 1; } /* 长时间按下键盘的键 */ else if(ie.value == 2) { msg.keybd.type = MESSAGE_TYPE_KEYBD_CLICK; msg.keybd.value = 2; } /* 哪个键 */ switch(ie.code) { case KEY_ESC: msg.keybd.code = INPUT_CODE_KEYBD_ESC; break; case KEY_1: msg.keybd.code = INPUT_CODE_KEYBD_1; break; case KEY_2: msg.keybd.code = INPUT_CODE_KEYBD_2; break; case KEY_3: msg.keybd.code = INPUT_CODE_KEYBD_3; break; case KEY_4: msg.keybd.code = INPUT_CODE_KEYBD_4; break; case KEY_5: msg.keybd.code = INPUT_CODE_KEYBD_5; break; case KEY_6: msg.keybd.code = INPUT_CODE_KEYBD_6; break; case KEY_7: msg.keybd.code = INPUT_CODE_KEYBD_7; break; case KEY_8: msg.keybd.code = INPUT_CODE_KEYBD_8; break; case KEY_9: msg.keybd.code = INPUT_CODE_KEYBD_9; break; case KEY_0: msg.keybd.code = INPUT_CODE_KEYBD_0; break; case KEY_MINUS: msg.keybd.code = INPUT_CODE_KEYBD_SUB; break; case KEY_EQUAL: msg.keybd.code = INPUT_CODE_KEYBD_EQUAL; break; case KEY_BACKSPACE: msg.keybd.code = INPUT_CODE_KEYBD_BACKSPACE; break; case KEY_TAB: msg.keybd.code = INPUT_CODE_KEYBD_TAB; break; case KEY_Q: msg.keybd.code = INPUT_CODE_KEYBD_Q; break; case KEY_W: msg.keybd.code = INPUT_CODE_KEYBD_W; break; case KEY_E: msg.keybd.code = INPUT_CODE_KEYBD_E; break; case KEY_R: msg.keybd.code = INPUT_CODE_KEYBD_R; break; case KEY_T: msg.keybd.code = INPUT_CODE_KEYBD_T; break; case KEY_Y: msg.keybd.code = INPUT_CODE_KEYBD_Y; break; case KEY_U: msg.keybd.code = INPUT_CODE_KEYBD_U; break; case KEY_I: msg.keybd.code = INPUT_CODE_KEYBD_I; break; case KEY_O: msg.keybd.code = INPUT_CODE_KEYBD_O; break; case KEY_P: msg.keybd.code = INPUT_CODE_KEYBD_P; break; case KEY_LEFTBRACE: msg.keybd.code = INPUT_CODE_KEYBD_L_BRACE; break; case KEY_RIGHTBRACE: msg.keybd.code = INPUT_CODE_KEYBD_R_BRACE; break; case KEY_ENTER: msg.keybd.code = INPUT_CODE_KEYBD_ENTER; break; case KEY_LEFTCTRL: msg.keybd.code = INPUT_CODE_KEYBD_L_CTRL; break; case KEY_A: msg.keybd.code = INPUT_CODE_KEYBD_A; break; case KEY_S: msg.keybd.code = INPUT_CODE_KEYBD_S; break; case KEY_D: msg.keybd.code = INPUT_CODE_KEYBD_D; break; case KEY_F: msg.keybd.code = INPUT_CODE_KEYBD_F; break; case KEY_G: msg.keybd.code = INPUT_CODE_KEYBD_G; break; case KEY_H: msg.keybd.code = INPUT_CODE_KEYBD_H; break; case KEY_J: msg.keybd.code = INPUT_CODE_KEYBD_J; break; case KEY_K: msg.keybd.code = INPUT_CODE_KEYBD_K; break; case KEY_L: msg.keybd.code = INPUT_CODE_KEYBD_L; break; case KEY_SEMICOLON: msg.keybd.code = INPUT_CODE_KEYBD_SEMICOLON; break; case KEY_APOSTROPHE: msg.keybd.code = INPUT_CODE_KEYBD_APOSTROPHE; break; case KEY_GRAVE: msg.keybd.code = INPUT_CODE_KEYBD_GRAVE; break; case KEY_LEFTSHIFT: msg.keybd.code = INPUT_CODE_KEYBD_L_SHIFT; break; case KEY_BACKSLASH: msg.keybd.code = INPUT_CODE_KEYBD_BACKSLASH; break; case KEY_Z: msg.keybd.code = INPUT_CODE_KEYBD_Z; break; case KEY_X: msg.keybd.code = INPUT_CODE_KEYBD_X; break; case KEY_C: msg.keybd.code = INPUT_CODE_KEYBD_C; break; case KEY_V: msg.keybd.code = INPUT_CODE_KEYBD_V; break; case KEY_B: msg.keybd.code = INPUT_CODE_KEYBD_B; break; case KEY_N: msg.keybd.code = INPUT_CODE_KEYBD_N; break; case KEY_M: msg.keybd.code = INPUT_CODE_KEYBD_M; break; case KEY_COMMA: msg.keybd.code = INPUT_CODE_KEYBD_COMMA; break; case KEY_DOT: msg.keybd.code = INPUT_CODE_KEYBD_DOT; break; case KEY_SLASH: msg.keybd.code = INPUT_CODE_KEYBD_SLASH; break; case KEY_RIGHTSHIFT: msg.keybd.code = INPUT_CODE_KEYBD_R_SHIFT; break; case KEY_KPASTERISK: msg.keybd.code = INPUT_CODE_KEYBD_KPASTERISK; break; case KEY_LEFTALT: msg.keybd.code = INPUT_CODE_KEYBD_L_ALT; break; case KEY_SPACE: msg.keybd.code = INPUT_CODE_KEYBD_SPACE; break; case KEY_CAPSLOCK: msg.keybd.code = INPUT_CODE_KEYBD_CAPSLOCK; break; case KEY_F1: msg.keybd.code = INPUT_CODE_KEYBD_F1; break; case KEY_F2: msg.keybd.code = INPUT_CODE_KEYBD_F2; break; case KEY_F3: msg.keybd.code = INPUT_CODE_KEYBD_F3; break; case KEY_F4: msg.keybd.code = INPUT_CODE_KEYBD_F4; break; case KEY_F5: msg.keybd.code = INPUT_CODE_KEYBD_F5; break; case KEY_F6: msg.keybd.code = INPUT_CODE_KEYBD_F6; break; case KEY_F7: msg.keybd.code = INPUT_CODE_KEYBD_F7; break; case KEY_F8: msg.keybd.code = INPUT_CODE_KEYBD_F8; break; case KEY_F9: msg.keybd.code = INPUT_CODE_KEYBD_F9; break; case KEY_F10: msg.keybd.code = INPUT_CODE_KEYBD_F10; break; case KEY_NUMLOCK: msg.keybd.code = INPUT_CODE_KEYBD_NUMLOCK; break; case KEY_SCROLLLOCK: msg.keybd.code = INPUT_CODE_KEYBD_SCROLLLOCK; break; case KEY_KP7: msg.keybd.code = INPUT_CODE_KEYBD_KP_7; break; case KEY_KP8: msg.keybd.code = INPUT_CODE_KEYBD_KP_8; break; case KEY_KP9: msg.keybd.code = INPUT_CODE_KEYBD_KP_9; break; case KEY_KPMINUS: msg.keybd.code = INPUT_CODE_KEYBD_KP_SUB; break; case KEY_KP4: msg.keybd.code = INPUT_CODE_KEYBD_KP_4; break; case KEY_KP5: msg.keybd.code = INPUT_CODE_KEYBD_KP_5; break; case KEY_KP6: msg.keybd.code = INPUT_CODE_KEYBD_KP_6; break; case KEY_KPPLUS: msg.keybd.code = INPUT_CODE_KEYBD_KP_ADD; break; case KEY_KP1: msg.keybd.code = INPUT_CODE_KEYBD_KP_1; break; case KEY_KP2: msg.keybd.code = INPUT_CODE_KEYBD_KP_2; break; case KEY_KP3: msg.keybd.code = INPUT_CODE_KEYBD_KP_3; break; case KEY_KP0: msg.keybd.code = INPUT_CODE_KEYBD_KP_0; break; case KEY_KPDOT: msg.keybd.code = INPUT_CODE_KEYBD_KP_DOT; break; case KEY_F11: msg.keybd.code = INPUT_CODE_KEYBD_F11; break; case KEY_F12: msg.keybd.code = INPUT_CODE_KEYBD_F12; break; case KEY_KPENTER: msg.keybd.code = INPUT_CODE_KEYBD_KP_ENTER; break; case KEY_RIGHTCTRL: msg.keybd.code = INPUT_CODE_KEYBD_R_CTRL; break; case KEY_KPSLASH: msg.keybd.code = INPUT_CODE_KEYBD_KP_SLASH; break; case KEY_SYSRQ: msg.keybd.code = INPUT_CODE_KEYBD_SYSRQ; break; case KEY_RIGHTALT: msg.keybd.code = INPUT_CODE_KEYBD_R_ALT; break; case KEY_HOME: msg.keybd.code = INPUT_CODE_KEYBD_HOME; break; case KEY_UP: msg.keybd.code = INPUT_CODE_KEYBD_UP; break; case KEY_PAGEUP: msg.keybd.code = INPUT_CODE_KEYBD_PAGEUP; break; case KEY_LEFT: msg.keybd.code = INPUT_CODE_KEYBD_LEFT; break; case KEY_RIGHT: msg.keybd.code = INPUT_CODE_KEYBD_RIGHT; break; case KEY_END: msg.keybd.code = INPUT_CODE_KEYBD_END; break; case KEY_DOWN: msg.keybd.code = INPUT_CODE_KEYBD_DOWN; break; case KEY_PAGEDOWN: msg.keybd.code = INPUT_CODE_KEYBD_PAGEDOWN; break; case KEY_INSERT: msg.keybd.code = INPUT_CODE_KEYBD_INSERT; break; case KEY_DELETE: msg.keybd.code = INPUT_CODE_KEYBD_DELETE; break; case KEY_PAUSE: msg.keybd.code = INPUT_CODE_KEYBD_PAUSE; break; case KEY_LEFTMETA: msg.keybd.code = INPUT_CODE_KEYBD_L_META; break; case KEY_RIGHTMETA: msg.keybd.code = INPUT_CODE_KEYBD_R_META; break; case KEY_COMPOSE: msg.keybd.code = INPUT_CODE_KEYBD_COMPOSE; break; default: break; } list_push_back(msg_list, &msg, sizeof(union message)); return 0; }
/** * @brief 用text_line全局样式对象初始化text_line对象 * * @param tl text_line指针 * * @return 成功返回0,否则返回-1 **/ static si_t text_line_init_with_default_style(struct text_line * tl) { char tmp_str[TMP_ARRAY_SIZE] = {'\0'}; si_t tmp_int = -1; /* text_line全局样式对象指针 */ struct text_line_style * style = &text_line_default_style; /* 如果text_line全局样式对象尚未加载配置 */ if(!style->flag) { struct config_parser parser; /* 初始化配置处理器 */ if(config_parser_init(TEXT_LINE_STYLE_FILE, &parser) != 0) { EGUI_PRINT_ERROR("fail to init text_line style from config file %s.", TEXT_LINE_STYLE_FILE); return -1; } /* 从配置读取各项配置,赋予style指针 */ config_parser_get_int(&parser, "area_x", &(style->area_x)); config_parser_get_int(&parser, "area_y", &(style->area_y)); config_parser_get_int(&parser, "area_width", &(style->area_width)); config_parser_get_int(&parser, "area_height", &(style->area_height)); config_parser_get_int(&parser, "border_size", &(style->border_size)); config_parser_get_int(&parser, "maximum_width", &(style->maximum_width)); config_parser_get_int(&parser, "minimum_width", &(style->minimum_width)); config_parser_get_int(&parser, "maximum_height", &(style->maximum_height)); config_parser_get_int(&parser, "minimum_height", &(style->minimum_height)); config_parser_get_str(&parser, "cursor", tmp_str); if((tmp_int = get_cursor_enum_from_str(tmp_str)) >= 0) { style->cursor = tmp_int; } config_parser_get_int(&parser, "back_color_r", &(style->back_color_r)); config_parser_get_int(&parser, "back_color_g", &(style->back_color_g)); config_parser_get_int(&parser, "back_color_b", &(style->back_color_b)); config_parser_get_int(&parser, "back_color_a", &(style->back_color_a)); config_parser_get_int(&parser, "fore_color_r", &(style->fore_color_r)); config_parser_get_int(&parser, "fore_color_g", &(style->fore_color_g)); config_parser_get_int(&parser, "fore_color_b", &(style->fore_color_b)); config_parser_get_int(&parser, "fore_color_a", &(style->fore_color_a)); config_parser_get_int(&parser, "frame_color_r", &(style->frame_color_r)); config_parser_get_int(&parser, "frame_color_g", &(style->frame_color_g)); config_parser_get_int(&parser, "frame_color_b", &(style->frame_color_b)); config_parser_get_int(&parser, "frame_color_a", &(style->frame_color_a)); tmp_int = -1; memset(tmp_str, 0, TMP_ARRAY_SIZE); config_parser_get_str(&parser, "font", tmp_str); if((tmp_int = get_font_enum_from_str(tmp_str)) >= 0) { style->font = tmp_int; } /* 退出配置处理器 */ config_parser_exit(&parser); style->flag = 1; } /* 用text_line默认样式初始化text_line各样式属性 */ tl->area.x = style->area_x; tl->area.y = style->area_y; tl->area.width = style->area_width; tl->area.height = style->area_height; tl->border_size = style->border_size; tl->maximum_width = style->maximum_width; tl->minimum_width = style->minimum_width; tl->maximum_height = style->maximum_height; tl->minimum_height = style->minimum_height; tl->cursor = style->cursor; tl->back_color.r = style->back_color_r; tl->back_color.g = style->back_color_g; tl->back_color.b = style->back_color_b; tl->back_color.a = style->back_color_a; tl->fore_color.r = style->fore_color_r; tl->fore_color.g = style->fore_color_g; tl->fore_color.b = style->fore_color_b; tl->fore_color.a = style->fore_color_a; tl->frame_color.r = style->frame_color_r; tl->frame_color.g = style->frame_color_g; tl->frame_color.b = style->frame_color_b; tl->frame_color.a = style->frame_color_a; tl->font = style->font; return 0; }
/* 总是将孩子节点加在子节点链的最右边 如果 parent 在对象树中 那么完成添加工作后一定要更新 root->parent 的 lchild 成员和 rchild 成员 这是为了保证遍历的正确 */ si_t application_add_window(struct window * parent, struct window * window) { struct object node, * tree; /* 添加顶层窗口 */ if(parent == NULL) { /* node 的父节点是 window */ node.parent = OBJECT_POINTER(window); node.lchild = object_tree_l_most_node(OBJECT_POINTER(window)); node.rchild = object_tree_r_most_node(OBJECT_POINTER(window)); node.name = NULL; node.id = 0; /* 将窗口添加到向量 */ vector_push_back(&(global_application.window_vector), &node, sizeof(struct object)); tree = vector_back(&(global_application.window_vector)); /* window 的父节点是 node */ window->parent = tree; } /* 添加非顶层窗口 */ else { object_insert_child(OBJECT_POINTER(parent), OBJECT_POINTER(window)); } /** * if already running in app_exec **/ if(global_application.exec_flag) { union message msg; msg.base.type = MESSAGE_TYPE_WIDGET_REPAINT; msg.widget_repaint.area = window->area; if(global_application.focus != NULL) { struct window* w = WINDOW_POINTER(global_application.focus); struct object* tree, *node, *tree_real_parent; w->is_activated = 0; msg.widget_repaint.area = w->area; if(w->callback != NULL) { w->callback(w, &msg); } node = OBJECT_POINTER(w); tree = node->parent; tree_real_parent = tree->parent; tree->parent = node; node = object_tree_l_most_node(tree); while(node != NULL) { union message msg; msg.base.type = MESSAGE_TYPE_WIDGET_REPAINT; msg.widget_repaint.area = WIDGET_POINTER(node)->area; if(WIDGET_POINTER(node)->callback != NULL) WIDGET_POINTER(node)->callback(node, &msg); node = object_tree_iterator_increment(tree, node); } tree->parent = tree_real_parent; } window->descriptor = register_window((parent == NULL ? 0 : parent->descriptor), window->title, window->area.x, window->area.y, window->area.width, window->area.height, window->minimize_enable, window->maximize_enable, window->modal); if(window->descriptor == 0) { EGUI_PRINT_ERROR("failed to register window"); application_exit(); return -1; } /** * find icon for the application **/ if((window->icon_path = (char*)malloc(256)) == NULL) { EGUI_PRINT_SYS_ERROR("failed to malloc for icon path. malloc"); application_exit(); return -1; } else { /** * in C89 standard, snprintf() is NOT included in <stdio.h> * so you have to use sprintf, which may be dangerous. be careful **/ sprintf(window->icon_path, "%s/icons/%s.bmp", global_application.icon_root_path, global_application.name); if(access(window->icon_path, R_OK) == -1) { sprintf(window->icon_path, "%s/icons/default.bmp", global_application.icon_root_path); } } msg.widget_repaint.area = window->area; global_application.focus = window; window->is_activated = 1; if(window->callback != NULL) { window->callback(window, &msg); } } return 0; }
int main() { struct egui_uds client_uds = {0}; si_t s_width = 0, s_height = 0, gd = 0; const char test_str[] = "hello, egui!"; struct rectangle area = {0}; /** * 初始化客户端通信句柄 **/ if(0 != uds_init(&client_uds, SOCK_STREAM, SERVER_PATH, PEER_ROLE_CLIENT)) { EGUI_PRINT_ERROR("Failed to init server uds"); return -1; } /** * 初始化客户端 **/ client_lib_init(&client_uds, NULL); EGUI_PRINT_INFO("client init sucessfully!"); /** * 获取屏幕的高和宽,输出 **/ s_width = get_screen_width(); s_height = get_screen_height(); if(s_width < 0 || s_height < 0) { EGUI_PRINT_ERROR("failed to get screen width or height"); return -1; } EGUI_PRINT_INFO("screen width = %d, height = %d", (int)s_width, (int)s_height); /** * 初始化图形设备 **/ gd = graphics_device_init(300, 300, 1000, 600, 255, 0, 0, 0, FONT_MATRIX_12); if(gd < 0) { EGUI_PRINT_ERROR("failed to init gd"); return -1; } /** * 显示字符串:hello egui **/ if(0 != show_text(gd, 300, 300, test_str, strlen(test_str)) || 0 != update(gd)) { EGUI_PRINT_ERROR("failed to show test \"%s\"", test_str); return -1; } /** * 图形设备退出 **/ if(0 != graphics_device_exit(gd)) { EGUI_PRINT_ERROR("failed to exit graph device"); return -1; } /** * 最大化窗口,输出返回的窗口大小 **/ if(0 != maximize_window(10, &area)) { EGUI_PRINT_ERROR("failed to max window"); return -1; } EGUI_PRINT_INFO("maximize window area = (%d, %d), %d, %d", (int)area.x, (int)area.y, (int)area.width, (int)area.height); if(0 != window_manager_quit()) { EGUI_PRINT_ERROR("failed to let window manager quit"); return -1; } /** * 清理通信句柄 **/ if(0 != uds_exit(&client_uds)) { EGUI_PRINT_ERROR("failed to clean uds"); return -1; } return 0; }