示例#1
0
static gboolean
on_incoming_message (GSocket      *socket,
                     GIOCondition  condition,
                     gpointer      user_data)
{
  g_debug (G_STRLOC ": %s: socket fd:%d", G_STRFUNC, g_socket_get_fd (socket));

  DasomIM *im = DASOM_IM (user_data);
  dasom_message_unref (im->result->reply);
  im->result->is_dispatched = TRUE;

  if (condition & (G_IO_HUP | G_IO_ERR))
  {
    /* Because two GSource is created over one socket,
     * when G_IO_HUP | G_IO_ERR, callback can run two times.
     * the following code avoid that callback runs two times. */
    GSource *source = g_main_current_source ();

    if (source == im->default_context_source)
      g_source_destroy (im->sockets_context_source);
    else if (source == im->sockets_context_source)
      g_source_destroy (im->default_context_source);

    if (!g_socket_is_closed (socket))
      g_socket_close (socket, NULL);

    im->result->reply    = NULL;

    g_critical (G_STRLOC ": %s: G_IO_HUP | G_IO_ERR", G_STRFUNC);

    return G_SOURCE_REMOVE;
  }

  DasomMessage *message;
  message = dasom_recv_message (socket);
  im->result->reply = message;
  gboolean retval;

  if (G_UNLIKELY (message == NULL))
  {
    g_critical (G_STRLOC ": NULL message");
    return G_SOURCE_CONTINUE;
  }

  switch (message->header->type)
  {
    /* reply */
    case DASOM_MESSAGE_FILTER_EVENT_REPLY:
    case DASOM_MESSAGE_RESET_REPLY:
    case DASOM_MESSAGE_FOCUS_IN_REPLY:
    case DASOM_MESSAGE_FOCUS_OUT_REPLY:
    case DASOM_MESSAGE_SET_SURROUNDING_REPLY:
    case DASOM_MESSAGE_GET_SURROUNDING_REPLY:
    case DASOM_MESSAGE_SET_CURSOR_LOCATION_REPLY:
    case DASOM_MESSAGE_SET_USE_PREEDIT_REPLY:
      break;
    /* signals */
    case DASOM_MESSAGE_PREEDIT_START:
      g_signal_emit_by_name (im, "preedit-start");
      dasom_send_message (socket, DASOM_MESSAGE_PREEDIT_START_REPLY, NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_PREEDIT_END:
      g_signal_emit_by_name (im, "preedit-end");
      dasom_send_message (socket, DASOM_MESSAGE_PREEDIT_END_REPLY, NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_PREEDIT_CHANGED:
      g_free (im->preedit_string);
      im->preedit_string = g_strndup (message->data,
                                      message->header->data_len - 1 - sizeof (gint));
      im->cursor_pos = *(gint *) (message->data +
                                  message->header->data_len - sizeof (gint));
      g_signal_emit_by_name (im, "preedit-changed");
      dasom_send_message (socket,
                          DASOM_MESSAGE_PREEDIT_CHANGED_REPLY,
                          NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_COMMIT:
      dasom_message_ref (message);
      g_signal_emit_by_name (im, "commit", (const gchar *) message->data);
      dasom_message_unref (message);
      dasom_send_message (socket, DASOM_MESSAGE_COMMIT_REPLY, NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_RETRIEVE_SURROUNDING:
      g_signal_emit_by_name (im, "retrieve-surrounding", &retval);
      dasom_send_message (socket, DASOM_MESSAGE_RETRIEVE_SURROUNDING_REPLY,
                          &retval, sizeof (gboolean), NULL);
      break;
    case DASOM_MESSAGE_DELETE_SURROUNDING:
      dasom_message_ref (message);
      g_signal_emit_by_name (im, "delete-surrounding",
                             ((gint *) message->data)[0],
                             ((gint *) message->data)[1], &retval);
      dasom_message_unref (message);
      dasom_send_message (socket, DASOM_MESSAGE_DELETE_SURROUNDING_REPLY,
                          &retval, sizeof (gboolean), NULL);
      break;
    default:
      g_warning (G_STRLOC ": %s: Unknown message type: %d", G_STRFUNC, message->header->type);
      break;
  }

  return G_SOURCE_CONTINUE;
}
示例#2
0
static gboolean
on_incoming_message_dasom (GSocket         *socket,
                           GIOCondition     condition,
                           DasomConnection *connection)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  DasomMessage *message;
  gboolean      retval;

  if (condition & (G_IO_HUP | G_IO_ERR))
  {
    g_debug (G_STRLOC ": condition & (G_IO_HUP | G_IO_ERR)");

    g_socket_close (socket, NULL);

    dasom_message_unref (connection->reply);
    connection->reply = NULL;

    if (G_UNLIKELY (connection->type == DASOM_CONNECTION_DASOM_AGENT))
      connection->server->agents_list =
        g_list_remove (connection->server->agents_list, connection);

    g_hash_table_remove (connection->server->connections,
                         GUINT_TO_POINTER (dasom_connection_get_id (connection)));

    return G_SOURCE_REMOVE;
  }

  if (connection->type == DASOM_CONNECTION_DASOM_IM)
    dasom_engine_set_english_mode (connection->engine,
                                   connection->is_english_mode);

  message = dasom_recv_message (socket);
  dasom_message_unref (connection->reply);
  connection->reply = message;
  connection->is_dispatched = TRUE;

  switch (message->header->type)
  {
    case DASOM_MESSAGE_FILTER_EVENT:
      dasom_message_ref (message);
      retval = dasom_connection_filter_event (connection,
                                              (DasomEvent *) message->data);
      dasom_message_unref (message);
      dasom_send_message (socket, DASOM_MESSAGE_FILTER_EVENT_REPLY, &retval,
                          sizeof (gboolean), NULL);
      break;
    case DASOM_MESSAGE_GET_PREEDIT_STRING:
      {
        gchar *data = NULL;
        gint   cursor_pos;
        gint   str_len = 0;

        dasom_connection_get_preedit_string (connection, &data, &cursor_pos);

        str_len = strlen (data);
        data = g_realloc (data, str_len + 1 + sizeof (gint));
        *(gint *) (data + str_len + 1) = cursor_pos;

        dasom_send_message (socket, DASOM_MESSAGE_GET_PREEDIT_STRING_REPLY,
                            data,
                            str_len + 1 + sizeof (gint),
                            NULL);
        g_free (data);
      }
      break;
    case DASOM_MESSAGE_RESET:
      dasom_connection_reset (connection);
      dasom_send_message (socket, DASOM_MESSAGE_RESET_REPLY, NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_FOCUS_IN:
      dasom_connection_focus_in (connection);
      dasom_send_message (socket, DASOM_MESSAGE_FOCUS_IN_REPLY, NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_FOCUS_OUT:
      dasom_connection_focus_out (connection);
      dasom_send_message (socket, DASOM_MESSAGE_FOCUS_OUT_REPLY, NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_SET_SURROUNDING:
      {
        dasom_message_ref (message);
        gchar   *data     = message->data;
        guint16  data_len = message->header->data_len;

        gint   str_len      = data_len - 1 - 2 * sizeof (gint);
        gint   cursor_index = *(gint *) (data + data_len - sizeof (gint));

        dasom_connection_set_surrounding (connection, data, str_len,
                                          cursor_index);
        dasom_message_unref (message);
        dasom_send_message (socket, DASOM_MESSAGE_SET_SURROUNDING_REPLY, NULL, 0, NULL);
      }
      break;
    case DASOM_MESSAGE_GET_SURROUNDING:
      {
        gchar *data;
        gint   cursor_index;
        gint   str_len = 0;

        retval = dasom_connection_get_surrounding (connection, &data,
                                                   &cursor_index);
        str_len = strlen (data);
        data = g_realloc (data, str_len + 1 + sizeof (gint) + sizeof (gboolean));
        *(gint *) (data + str_len + 1) = cursor_index;
        *(gboolean *) (data + str_len + 1 + sizeof (gint)) = retval;

        dasom_send_message (socket, DASOM_MESSAGE_GET_SURROUNDING_REPLY,
                            data,
                            str_len + 1 + sizeof (gint) + sizeof (gboolean),
                            NULL);
        g_free (data);
      }
      break;
    case DASOM_MESSAGE_SET_CURSOR_LOCATION:
      dasom_message_ref (message);
      dasom_connection_set_cursor_location (connection,
                                            (DasomRectangle *) message->data);
      dasom_message_unref (message);
      dasom_send_message (socket, DASOM_MESSAGE_SET_CURSOR_LOCATION_REPLY,
                          NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_SET_USE_PREEDIT:
      dasom_message_ref (message);
      dasom_connection_set_use_preedit (connection, *(gboolean *) message->data);
      dasom_message_unref (message);
      dasom_send_message (socket, DASOM_MESSAGE_SET_USE_PREEDIT_REPLY,
                          NULL, 0, NULL);
      break;
    case DASOM_MESSAGE_PREEDIT_START_REPLY:
    case DASOM_MESSAGE_PREEDIT_CHANGED_REPLY:
    case DASOM_MESSAGE_PREEDIT_END_REPLY:
    case DASOM_MESSAGE_COMMIT_REPLY:
    case DASOM_MESSAGE_RETRIEVE_SURROUNDING_REPLY:
    case DASOM_MESSAGE_DELETE_SURROUNDING_REPLY:
      break;
    default:
      g_warning ("Unknown message type: %d", message->header->type);
      break;
  }

  if (connection->type == DASOM_CONNECTION_DASOM_IM)
    connection->is_english_mode =
      dasom_engine_get_english_mode (connection->engine);

  return G_SOURCE_CONTINUE;
}