void export_text_xim() { char *text = output_buffer; if (!output_bufferN) return; XTextProperty tp; #if 0 char outbuf[512]; utf8_big5(output_buffer, outbuf); text = outbuf; XmbTextListToTextProperty(dpy, &text, 1, XCompoundTextStyle, &tp); #else Xutf8TextListToTextProperty(dpy, &text, 1, XCompoundTextStyle, &tp); #endif #if DEBUG && 0 dbg("send_utf8_ch: %s\n", text); #endif ((IMCommitStruct*)current_forward_eve)->flag |= XimLookupChars; ((IMCommitStruct*)current_forward_eve)->commit_string = (char *)tp.value; IMCommitString(current_ims, (XPointer)current_forward_eve); clear_output_buffer(); XFree(tp.value); }
/*--------------------------------------------------------------------------*/ void create_output_buffer(Map* map, BufferTile* buf, int size) { /* Spieler in die Mitte, seine Position als Versatz benutzen */ int i, j, translated_x, translated_y, center_x, center_y; Spawn* spawn = get_player_spawn(map); if(spawn == NULL) { fprintf(stderr, "Keine Spielfigur vorhanden!\n"); exit(1); } clear_output_buffer(buf, size); center_x = OUTPUT_IN_GLYPHS_X / 2 + 1; center_y = OUTPUT_IN_GLYPHS_Y / 2 + 1; translated_x = center_x - spawn->x; translated_y = center_y - spawn->y; j = 0; for(i = 0; i < size; ++i) { unsigned int current_x, current_y; if(i != 0 && (i % (OUTPUT_IN_GLYPHS_X)) == 0) { ++j; } current_y = j; current_x = i % OUTPUT_IN_GLYPHS_X; /* unteres Renderende erreicht */ if(current_y == OUTPUT_IN_GLYPHS_Y) { break; } /* Hier Kartenteil? */ if(translated_x <= (int)current_x && translated_y <= (int)current_y && current_x < (translated_x + map->x) && current_y < (translated_y + map->y)) { render_tile(&buf[i], &map->tiles[(current_y - translated_y) * map->x + (current_x - translated_x)], map); } } }
static void destroy_ssl(struct st_h2o_socket_ssl_t *ssl) { SSL_free(ssl->ssl); ssl->ssl = NULL; h2o_buffer_dispose(&ssl->input.encrypted); clear_output_buffer(ssl); free(ssl); }
void h2o_socket_write(h2o_socket_t *sock, h2o_iovec_t *bufs, size_t bufcnt, h2o_socket_cb cb) { size_t i, prev_bytes_written = sock->bytes_written; for (i = 0; i != bufcnt; ++i) { sock->bytes_written = bufs[i].len; #if H2O_SOCKET_DUMP_WRITE fprintf(stderr, "writing %zu bytes to fd:%d\n", bufs[i].len, h2o_socket_get_fd(sock)); h2o_dump_memory(stderr, bufs[i].base, bufs[i].len); #endif } if (sock->ssl == NULL) { do_write(sock, bufs, bufcnt, cb); } else { assert(sock->ssl->output.bufs.size == 0); /* fill in the data */ size_t ssl_record_size; switch (sock->_latency_optimization.state) { case H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_TBD: case H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_DISABLED: ssl_record_size = prev_bytes_written < 200 * 1024 ? calc_suggested_tls_payload_size(sock, 1400) : 16384; break; case H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_DETERMINED: sock->_latency_optimization.state = H2O_SOCKET_LATENCY_OPTIMIZATION_STATE_NEEDS_UPDATE; /* fallthru */ default: ssl_record_size = sock->_latency_optimization.suggested_tls_payload_size; break; } for (; bufcnt != 0; ++bufs, --bufcnt) { size_t off = 0; while (off != bufs[0].len) { int ret; size_t sz = bufs[0].len - off; if (sz > ssl_record_size) sz = ssl_record_size; ret = SSL_write(sock->ssl->ssl, bufs[0].base + off, (int)sz); if (ret != sz) { /* The error happens if SSL_write is called after SSL_read returns a fatal error (e.g. due to corrupt TCP packet * being received). We need to take care of this since some protocol implementations send data after the read- * side of the connection gets closed (note that protocol implementations are (yet) incapable of distinguishing * a normal shutdown and close due to an error using the `status` value of the read callback). */ clear_output_buffer(sock->ssl); flush_pending_ssl(sock, cb); #ifndef H2O_USE_LIBUV ((struct st_h2o_evloop_socket_t *)sock)->_flags |= H2O_SOCKET_FLAG_IS_WRITE_ERROR; #endif return; } off += sz; } } flush_pending_ssl(sock, cb); } }
static void destroy_ssl(struct st_h2o_socket_ssl_t *ssl) { if (!ssl->ssl->server) free(ssl->handshake.client.server_name); SSL_free(ssl->ssl); ssl->ssl = NULL; h2o_buffer_dispose(&ssl->input.encrypted); clear_output_buffer(ssl); free(ssl); }
void on_write_complete(h2o_socket_t *sock, int status) { h2o_socket_cb cb; if (sock->ssl != NULL) clear_output_buffer(sock->ssl); cb = sock->_cb.write; sock->_cb.write = NULL; cb(sock, status); }
void on_write_complete(h2o_socket_t *sock, const char *err) { h2o_socket_cb cb; if (sock->ssl != NULL) clear_output_buffer(sock->ssl); cb = sock->_cb.write; sock->_cb.write = NULL; cb(sock, err); }
static void destroy_ssl(struct st_h2o_socket_ssl_t *ssl) { if (!SSL_is_server(ssl->ssl)) { free(ssl->handshake.client.server_name); free(ssl->handshake.client.session_cache_key.base); } SSL_free(ssl->ssl); ssl->ssl = NULL; h2o_buffer_dispose(&ssl->input.encrypted); clear_output_buffer(ssl); free(ssl); }
void h2o_socket_write(h2o_socket_t *sock, h2o_iovec_t *bufs, size_t bufcnt, h2o_socket_cb cb) { #if H2O_SOCKET_DUMP_WRITE { size_t i; for (i = 0; i != bufcnt; ++i) { fprintf(stderr, "writing %zu bytes to fd:%d\n", bufs[i].len, #if H2O_USE_LIBUV ((struct st_h2o_uv_socket_t *)sock)->uv.stream->io_watcher.fd #else ((struct st_h2o_evloop_socket_t *)sock)->fd #endif ); h2o_dump_memory(stderr, bufs[i].base, bufs[i].len); } } #endif if (sock->ssl == NULL) { do_write(sock, bufs, bufcnt, cb); } else { assert(sock->ssl->output.bufs.size == 0); /* fill in the data */ for (; bufcnt != 0; ++bufs, --bufcnt) { size_t off = 0; while (off != bufs[0].len) { int ret; size_t sz = bufs[0].len - off; if (sz > 1400) sz = 1400; ret = SSL_write(sock->ssl->ssl, bufs[0].base + off, (int)sz); if (ret != sz) { /* The error happens if SSL_write is called after SSL_read returns a fatal error (e.g. due to corrupt TCP packet * being received). We need to take care of this since some protocol implementations send data after the read- * side of the connection gets closed (note that protocol implementations are (yet) incapable of distinguishing * a normal shutdown and close due to an error using the `status` value of the read callback). */ clear_output_buffer(sock->ssl); flush_pending_ssl(sock, cb); #ifndef H2O_USE_LIBUV ((struct st_h2o_evloop_socket_t *)sock)->_flags |= H2O_SOCKET_FLAG_IS_WRITE_ERROR; #endif return; } off += sz; } } flush_pending_ssl(sock, cb); } }
static void proceed_handshake(h2o_socket_t *sock, const char *err) { h2o_iovec_t first_input = {NULL}; int ret; sock->_cb.write = NULL; if (err != NULL) { goto Complete; } if (sock->ssl->handshake.server.async_resumption.state == ASYNC_RESUMPTION_STATE_RECORD) { if (sock->ssl->input.encrypted->size <= 1024) { /* retain a copy of input if performing async resumption */ first_input = h2o_iovec_init(alloca(sock->ssl->input.encrypted->size), sock->ssl->input.encrypted->size); memcpy(first_input.base, sock->ssl->input.encrypted->bytes, first_input.len); } else { sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE; } } Redo: if (SSL_is_server(sock->ssl->ssl)) { ret = SSL_accept(sock->ssl->ssl); } else { ret = SSL_connect(sock->ssl->ssl); } switch (sock->ssl->handshake.server.async_resumption.state) { case ASYNC_RESUMPTION_STATE_RECORD: /* async resumption has not been triggered; proceed the state to complete */ sock->ssl->handshake.server.async_resumption.state = ASYNC_RESUMPTION_STATE_COMPLETE; break; case ASYNC_RESUMPTION_STATE_REQUEST_SENT: { /* sent async request, reset the ssl state, and wait for async response */ assert(ret < 0); SSL_CTX *ssl_ctx = SSL_get_SSL_CTX(sock->ssl->ssl); SSL_free(sock->ssl->ssl); create_ssl(sock, ssl_ctx); clear_output_buffer(sock->ssl); h2o_buffer_consume(&sock->ssl->input.encrypted, sock->ssl->input.encrypted->size); h2o_buffer_reserve(&sock->ssl->input.encrypted, first_input.len); memcpy(sock->ssl->input.encrypted->bytes, first_input.base, first_input.len); sock->ssl->input.encrypted->size = first_input.len; h2o_socket_read_stop(sock); return; } default: break; } if (ret == 0 || (ret < 0 && SSL_get_error(sock->ssl->ssl, ret) != SSL_ERROR_WANT_READ)) { /* failed */ long verify_result = SSL_get_verify_result(sock->ssl->ssl); if (verify_result != X509_V_OK) { err = X509_verify_cert_error_string(verify_result); } else { err = "ssl handshake failure"; } goto Complete; } if (sock->ssl->output.bufs.size != 0) { h2o_socket_read_stop(sock); flush_pending_ssl(sock, ret == 1 ? on_handshake_complete : proceed_handshake); } else { if (ret == 1) { if (!SSL_is_server(sock->ssl->ssl)) { X509 *cert = SSL_get_peer_certificate(sock->ssl->ssl); if (cert != NULL) { switch (validate_hostname(sock->ssl->handshake.client.server_name, cert)) { case MatchFound: /* ok */ break; case MatchNotFound: err = h2o_socket_error_ssl_cert_name_mismatch; break; default: err = h2o_socket_error_ssl_cert_invalid; break; } X509_free(cert); } else { err = h2o_socket_error_ssl_no_cert; } } goto Complete; } if (sock->ssl->input.encrypted->size != 0) goto Redo; h2o_socket_read_start(sock, proceed_handshake); } return; Complete: h2o_socket_read_stop(sock); on_handshake_complete(sock, err); }
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; } }