void create_win_save_phrase(WSP_S *wsp, int wspN) { #if WIN32 if (test_mode) return; #endif if (!wspN) return; SAVE_SESS *sess = tzmalloc(SAVE_SESS, 1); GtkWidget *main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_has_resize_grip(GTK_WINDOW(main_window), FALSE); sess->win = main_window; gtk_window_set_default_size(GTK_WINDOW (main_window), 20, 10); gtk_window_set_title(GTK_WINDOW(main_window), _(_L("加片語到詞庫"))); #if 0 g_signal_connect (G_OBJECT (main_window), "delete_event", G_CALLBACK (delete_event), sess); #endif GtkWidget *vbox = gtk_vbox_new (FALSE, 0); gtk_orientable_set_orientation(GTK_ORIENTABLE(vbox), GTK_ORIENTATION_VERTICAL); gtk_container_add (GTK_CONTAINER (main_window), vbox); char tt[512]; tt[0] = 0; wsp_str(wsp, wspN, tt); gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new(tt), FALSE, FALSE, 0); int i; for(i=0; i<wspN; i++) { if (ph_key_sz==2) strcat(tt, phokey_to_str(wsp[i].key)); strcat(tt, " "); } if (tt[0]) gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new(tt), FALSE, FALSE, 0); sess->mywsp = tmemdup(wsp, WSP_S, wspN); sess->mywspN = wspN; GtkWidget *hbox_cancel_ok = gtk_hbox_new (FALSE, 10); gtk_box_pack_start (GTK_BOX (vbox), hbox_cancel_ok , FALSE, FALSE, 5); GtkWidget *button_ok = gtk_button_new_from_stock (GTK_STOCK_OK); gtk_box_pack_start (GTK_BOX (hbox_cancel_ok), button_ok, TRUE, TRUE, 5); GtkWidget *button_cancel = gtk_button_new_from_stock (GTK_STOCK_CANCEL); gtk_box_pack_start (GTK_BOX (hbox_cancel_ok), button_cancel, TRUE, TRUE, 0); sess->label_countdown = gtk_label_new(NULL); gtk_box_pack_start (GTK_BOX (vbox), sess->label_countdown, FALSE, FALSE, 5); #if 1 #if WIN32 set_no_focus(main_window); #endif gtk_widget_realize(main_window); #if UNIX set_no_focus(main_window); #else win32_init_win(main_window); #endif #endif // dbg("mmmmmmmmmmmmm\n"); GTK_WIDGET_SET_FLAGS (button_ok, GTK_CAN_DEFAULT); gtk_widget_grab_default (button_ok); #if 1 // dbg("main_window %x\n", main_window); g_signal_connect (G_OBJECT (button_cancel), "clicked", G_CALLBACK (close_win_save_phrase), sess); g_signal_connect (G_OBJECT (button_ok), "clicked", G_CALLBACK (cb_ok), sess); #endif gtk_window_present(GTK_WINDOW(main_window)); gtk_window_set_keep_above(GTK_WINDOW(main_window), TRUE); // gtk_window_set_modal(GTK_WINDOW(main_window), TRUE); sess->countdown = 3; disp_countdown(sess); sess->countdown_handle = g_timeout_add(1000, timeout_countdown, sess); gtk_widget_show_all(main_window); }
static HIME_client_handle *hime_im_client_reopen(HIME_client_handle *hime_ch, Display *dpy) { // dbg("hime_im_client_reopen\n"); int dbg_msg = getenv("HIME_CONNECT_MSG_ON") != NULL; int sockfd=0; int servlen; // char *addr; Server_IP_port srv_ip_port; #if DEBUG u_char *pp; #endif int uid = getuid(); if (uid > 0 && uid < 500) { is_special_user = TRUE; } int tcp = FALSE; HIME_client_handle *handle; int rstatus; // dbg("hime_im_client_reopen\n"); if (!dpy) { dbg("null disp %d\n", hime_ch->fd); goto next; } Atom hime_addr_atom = get_hime_addr_atom(dpy); Window hime_win = None; #define MAX_TRY 3 int loop; if (!is_special_user) for(loop=0; loop < MAX_TRY; loop++) { if ((hime_win=find_hime_window(dpy))!=None || getenv("HIME_IM_CLIENT_NO_AUTO_EXEC")) break; static time_t exec_time; if (time(NULL) - exec_time > 1 /* && count < 5 */) { time(&exec_time); dbg("XGetSelectionOwner: old version of hime or hime is not running ??\n"); static char execbin[]=HIME_BIN_DIR"/hime"; dbg("... try to start a new hime server %s\n", execbin); int pid; if ((pid=fork())==0) { setenv("HIME_DAEMON", "", TRUE); execl(execbin, "hime", NULL); } else { int status; // hime will daemon() waitpid(pid, &status, 0); } } } if (loop == MAX_TRY || hime_win == None) { goto next; } Atom actual_type; int actual_format; u_long nitems,bytes_after; char *message_sock = NULL; Atom hime_sockpath_atom = get_hime_sockpath_atom(dpy); // printf("hime_sockpath_atom %d\n", hime_sockpath_atom); if (!hime_sockpath_atom || XGetWindowProperty(dpy, hime_win, hime_sockpath_atom, 0, 64, False, AnyPropertyType, &actual_type, &actual_format, &nitems,&bytes_after,(u_char **)&message_sock) != Success) { #if DBG || 1 dbg("XGetWindowProperty 2: old version of hime or hime is not running ??\n"); #endif goto next; } Server_sock_path srv_sock_path; srv_sock_path.sock_path[0] = 0; if (message_sock) { memcpy(&srv_sock_path, message_sock, sizeof(srv_sock_path)); XFree(message_sock); } else goto next; struct sockaddr_un serv_addr; bzero((char *) &serv_addr,sizeof(serv_addr)); serv_addr.sun_family = AF_UNIX; char sock_path[UNIX_PATH_MAX]; if (srv_sock_path.sock_path[0]) { strcpy(sock_path, srv_sock_path.sock_path); } else { get_hime_im_srv_sock_path(sock_path, sizeof(sock_path)); } // addr = sock_path; strcpy(serv_addr.sun_path, sock_path); #ifdef SUN_LEN servlen = SUN_LEN(&serv_addr); #else servlen = strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family); #endif if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { perror("cannot open socket"); goto tcp; } if (connect(sockfd, (struct sockaddr *)&serv_addr, servlen) < 0) { close(sockfd); sockfd = 0; goto tcp; } if (dbg_msg) dbg("connected to unix socket addr %s\n", sock_path); goto next; char *message; tcp: message = NULL; if (!hime_addr_atom || XGetWindowProperty(dpy, hime_win, hime_addr_atom, 0, 64, False, AnyPropertyType, &actual_type, &actual_format, &nitems,&bytes_after,(u_char **)&message) != Success) { #if DBG || 1 dbg("XGetWindowProperty: old version of hime or hime is not running ??\n"); #endif goto next; } if (message) { memcpy(&srv_ip_port, message, sizeof(srv_ip_port)); XFree(message); } else goto next; // dbg("im server tcp port %d\n", ntohs(srv_ip_port.port)); struct sockaddr_in in_serv_addr; bzero((char *) &in_serv_addr, sizeof(in_serv_addr)); in_serv_addr.sin_family = AF_INET; in_serv_addr.sin_addr.s_addr = srv_ip_port.ip; in_serv_addr.sin_port = srv_ip_port.port; servlen = sizeof(in_serv_addr); if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("cannot open socket"); goto next; } dbg("sock %d\n", sockfd); if (connect(sockfd, (struct sockaddr *)&in_serv_addr, servlen) < 0) { dbg("hime_im_client_open cannot open: ") ; perror(""); close(sockfd); sockfd = 0; goto next; } #if DEBUG pp = (u_char *)&srv_ip_port.ip; if (dbg_msg) dbg("hime client connected to server %d.%d.%d.%d:%d\n", pp[0], pp[1], pp[2], pp[3], ntohs(srv_ip_port.port)); #endif tcp = TRUE; next: if (!hime_ch) handle = tzmalloc(HIME_client_handle, 1); else { handle = hime_ch; } if (sockfd < 0) sockfd = 0; if (sockfd > 0) { handle->fd = sockfd; if (tcp) { if (!handle->passwd) handle->passwd = malloc(sizeof(HIME_PASSWD)); memcpy(handle->passwd, &srv_ip_port.passwd, sizeof(srv_ip_port.passwd)); } else { if (handle->passwd) { free(handle->passwd); handle->passwd = NULL; } } } if (handle->fd) { if (BITON(handle->flag, FLAG_HIME_client_handle_has_focus)) hime_im_client_focus_in(handle); hime_im_client_set_flags(handle, flags_backup, &rstatus); } return handle; }
void process_client_req(int fd) { HIME_req req; #if DBG dbg("svr--> process_client_req %d\n", fd); #endif int rn = myread(fd, &req, sizeof(req)); if (rn <= 0) { shutdown_client(fd); return; } if (hime_clients[fd].type == Connection_type_tcp) { __hime_enc_mem((u_char *)&req, sizeof(req), &srv_ip_port.passwd, &hime_clients[fd].seed); } to_hime_endian_4(&req.req_no); to_hime_endian_4(&req.client_win); to_hime_endian_4(&req.flag); to_hime_endian_2(&req.spot_location.x); to_hime_endian_2(&req.spot_location.y); // dbg("spot %d %d\n", req.spot_location.x, req.spot_location.y); ClientState *cs = NULL; if (current_CS && req.client_win == current_CS->client_win) { cs = current_CS; } else { int idx = fd; cs = hime_clients[fd].cs; int new_cli = 0; if (!cs) { cs = hime_clients[idx].cs = tzmalloc(ClientState, 1); new_cli = 1; } cs->client_win = req.client_win; cs->b_hime_protocol = TRUE; cs->input_style = InputStyleOverSpot; if (hime_init_im_enabled && ((hime_single_state && !is_init_im_enabled) || (!hime_single_state && new_cli))) { dbg("new_cli default_input_method:%d\n", default_input_method); is_init_im_enabled = TRUE; current_CS = cs; save_CS_temp_to_current(); init_state_chinese(cs); } } if (!cs) p_err("bad cs\n"); if (req.req_no != HIME_req_message) { cs->spot_location.x = req.spot_location.x; cs->spot_location.y = req.spot_location.y; } gboolean status; HIME_reply reply; bzero(&reply, sizeof(reply)); switch (req.req_no) { case HIME_req_key_press: case HIME_req_key_release: current_CS = cs; save_CS_temp_to_current(); #if DBG && 0 { char tt[128]; if (req.keyeve.key < 127) { sprintf(tt,"'%c'", req.keyeve.key); } else { strcpy(tt, XKeysymToString(req.keyeve.key)); } dbg_time("HIME_key_press %x %s\n", cs, tt); } #endif to_hime_endian_4(&req.keyeve.key); to_hime_endian_4(&req.keyeve.state); // dbg("serv key eve %x %x predit:%d\n",req.keyeve.key, req.keyeve.state, cs->use_preedit); #if DBG char *typ; typ="press"; #endif #if 0 if (req.req_no==HIME_req_key_press) status = Process2KeyPress(req.keyeve.key, req.keyeve.state); else { status = Process2KeyRelease(req.keyeve.key, req.keyeve.state); #else if (req.req_no==HIME_req_key_press) status = ProcessKeyPress(req.keyeve.key, req.keyeve.state); else { status = ProcessKeyRelease(req.keyeve.key, req.keyeve.state); #endif #if DBG typ="rele"; #endif } if (status) reply.flag |= HIME_reply_key_processed; #if DBG dbg("%s srv flag:%x status:%d len:%d %x %c\n",typ, reply.flag, status, output_bufferN, req.keyeve.key,req.keyeve.key & 0x7f); #endif int datalen; datalen = reply.datalen = output_bufferN ? output_bufferN + 1 : 0; // include '\0' to_hime_endian_4(&reply.flag); to_hime_endian_4(&reply.datalen); write_enc(fd, &reply, sizeof(reply)); // dbg("server reply.flag %x\n", reply.flag); if (output_bufferN) { write_enc(fd, output_buffer, datalen); clear_output_buffer(); } break; case HIME_req_focus_in: #if DBG dbg_time("HIME_req_focus_in %x %d %d\n",cs, cs->spot_location.x, cs->spot_location.y); #endif // current_CS = cs; hime_FocusIn(cs); break; case HIME_req_focus_out: #if DBG dbg_time("HIME_req_focus_out %x\n", cs); #endif hime_FocusOut(cs); break; case HIME_req_focus_out2: { #if DBG dbg_time("HIME_req_focus_out2 %x\n", cs); #endif if (hime_FocusOut(cs)) flush_edit_buffer(); HIME_reply reply; bzero(&reply, sizeof(reply)); int datalen = reply.datalen = output_bufferN ? output_bufferN + 1 : 0; // include '\0' to_hime_endian_4(&reply.flag); to_hime_endian_4(&reply.datalen); write_enc(fd, &reply, sizeof(reply)); // dbg("server reply.flag %x\n", reply.flag); if (output_bufferN) { write_enc(fd, output_buffer, datalen); clear_output_buffer(); } } break; case HIME_req_set_cursor_location: #if DBG dbg_time("set_cursor_location %x %d %d\n", cs, cs->spot_location.x, cs->spot_location.y); #endif update_in_win_pos(); break; case HIME_req_set_flags: // dbg("HIME_req_set_flags\n"); if (BITON(req.flag, FLAG_HIME_client_handle_raise_window)) { #if DBG dbg("********* raise * window\n"); #endif if (!hime_pop_up_win) cs->b_raise_window = TRUE; } if (req.flag & FLAG_HIME_client_handle_use_preedit) cs->use_preedit = TRUE; int rflags; rflags = 0; if (hime_pop_up_win) rflags = FLAG_HIME_srv_ret_status_use_pop_up; write_enc(fd, &rflags, sizeof(rflags)); break; case HIME_req_get_preedit: { #if DBG dbg("svr HIME_req_get_preedit %x\n", cs); #endif char str[HIME_PREEDIT_MAX_STR]; HIME_PREEDIT_ATTR attr[HIME_PREEDIT_ATTR_MAX_N]; int cursor, sub_comp_len; int attrN = hime_get_preedit(cs, str, attr, &cursor, &sub_comp_len); if (hime_edit_display&(HIME_EDIT_DISPLAY_BOTH|HIME_EDIT_DISPLAY_OVER_THE_SPOT)) cursor=0; if (hime_edit_display&HIME_EDIT_DISPLAY_OVER_THE_SPOT) { attrN=0; str[0]=0; } int len = strlen(str)+1; // including \0 write_enc(fd, &len, sizeof(len)); write_enc(fd, str, len); // dbg("attrN:%d\n", attrN); write_enc(fd, &attrN, sizeof(attrN)); if (attrN > 0) write_enc(fd, attr, sizeof(HIME_PREEDIT_ATTR)*attrN); write_enc(fd, &cursor, sizeof(cursor)); write_enc(fd, &sub_comp_len, sizeof(sub_comp_len)); // dbg("uuuuuuuuuuuuuuuuu len:%d %d cursor:%d\n", len, attrN, cursor); } break; case HIME_req_reset: hime_reset(); break; case HIME_req_message: { // dbg("HIME_req_message\n"); short len=0; int rn = myread(fd, &len, sizeof(len)); if (rn <= 0) { cli_down: shutdown_client(fd); return; } // only unix socket, no decrypt char buf[512]; // message should include '\0' if (len > 0 && len < sizeof(buf)) { if (myread(fd, buf, len)<=0) goto cli_down; message_cb(buf); } } break; default: dbg_time("Invalid request %x from:", req.req_no); struct sockaddr_in addr; socklen_t len=sizeof(addr); bzero(&addr, sizeof(addr)); if (!getpeername(fd, (struct sockaddr *)&addr, &len)) { dbg("%s\n", inet_ntoa(addr.sin_addr)); } else { perror("getpeername\n"); } shutdown_client(fd); break; } }