static void channel_ready (GObject *source, GAsyncResult *result, gpointer user_data) { ChVisitor *visitor = (ChVisitor*) user_data; TpChannel *channel; const gchar *ident; TpMessage *message; GError *error = NULL; if (!tp_proxy_prepare_finish (source, result, &error)) { g_printerr ("error loading channel: %s\n", error->message); return; } channel = TP_CHANNEL (source); ident = tp_channel_get_identifier (channel); if (verbose > 0) { g_printerr ("channel ready \"%s\" (type %s)\n", ident, tp_channel_get_channel_type (channel)); } GList *messages, *iter; if (TP_IS_TEXT_CHANNEL (channel)) { messages = tp_text_channel_dup_pending_messages ( TP_TEXT_CHANNEL (channel)); for (iter = messages; iter; iter = iter->next) { TpMessage *message = TP_MESSAGE (iter->data); message_cb (message); } if (acknowledge) { tp_text_channel_ack_messages_async (TP_TEXT_CHANNEL (channel), messages, ack_messages_cb, NULL); } g_list_free_full (messages, g_object_unref); if (send_message && !has_sent_message_to (ident)) { message = tp_client_message_new_text(0, msg_buffer); g_ptr_array_add (messages_sent, g_strdup (ident)); ch_visitor_incref (visitor); tp_text_channel_send_message_async (TP_TEXT_CHANNEL (channel), message, 0, send_message_cb, visitor); } } else { g_printerr ("error loading channel: %s is not a text channel\n", tp_channel_get_identifier (channel)); } ch_visitor_decref (visitor); }
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; } }