示例#1
0
文件: eve.c 项目: CarterTsai/hime
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);
}
示例#2
0
文件: main.c 项目: MarcelHB/c37
/*--------------------------------------------------------------------------*/
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);
        }
    }
}
示例#3
0
文件: socket.c 项目: Robert-Xie/h2o
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);
}
示例#4
0
文件: socket.c 项目: deweerdt/h2o
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);
    }
}
示例#5
0
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);
}
示例#6
0
文件: socket.c 项目: Robert-Xie/h2o
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);
}
示例#7
0
文件: socket.c 项目: deweerdt/h2o
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);
}
示例#8
0
文件: socket.c 项目: deweerdt/h2o
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);
}
示例#9
0
文件: socket.c 项目: Robert-Xie/h2o
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);
    }
}
示例#10
0
文件: socket.c 项目: deweerdt/h2o
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);
}
示例#11
0
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;
  }
}