static gboolean
on_new_connection (GSocketService    *service,
                   GSocketConnection *socket_connection,
                   GObject           *source_object,
                   DasomServer       *server)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  /* TODO: simple authentication using GCredentials */

  GSocket *socket = g_socket_connection_get_socket (socket_connection);

  DasomMessage *message;
  message = dasom_recv_message (socket);

  if (message->header->type == DASOM_MESSAGE_CONNECT)
    dasom_send_message (socket, DASOM_MESSAGE_CONNECT_REPLY, NULL, 0, NULL);
  else
  {
    /* TODO: error handling */
    dasom_send_message (socket, DASOM_MESSAGE_ERROR, NULL, 0, NULL);
    return TRUE; /* TODO: what happened if return value is FALSE */
  }

  DasomConnection *connection;
  connection = dasom_connection_new (*(DasomConnectionType *) message->data,
                                     dasom_server_get_default_engine (server), NULL);
  dasom_message_unref (message);
  connection->socket = socket;
  dasom_server_add_connection (server, connection);

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

  connection->source = g_socket_create_source (socket, G_IO_IN, NULL);
  connection->socket_connection = g_object_ref (socket_connection);
  g_source_set_can_recurse (connection->source, TRUE);
  g_source_set_callback (connection->source,
                         (GSourceFunc) on_incoming_message_dasom,
                         connection, NULL);
  g_source_attach (connection->source, server->main_context);

  return TRUE;
}
Example #2
0
gboolean dasom_im_get_surrounding (DasomIM  *im,
                                   gchar   **text,
                                   gint     *cursor_index)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  g_return_val_if_fail (DASOM_IS_IM (im), FALSE);

  GSocket *socket = g_socket_connection_get_socket (im->connection);
  if (!socket || g_socket_is_closed (socket))
  {
    if (text)
      *text = g_strdup ("");

    if (cursor_index)
      *cursor_index = 0;

    g_warning ("socket is closed");

    return FALSE;
  }

  dasom_send_message (socket, DASOM_MESSAGE_GET_SURROUNDING, NULL, 0, NULL);
  dasom_result_iteration_until (im->result,
                                dasom_im_sockets_context,
                                DASOM_MESSAGE_GET_SURROUNDING_REPLY);

  if (im->result->reply == NULL)
  {
    if (text)
      *text = g_strdup ("");

    if (cursor_index)
      *cursor_index = 0;

    return FALSE;
  }

  if (text)
    *text = g_strndup (im->result->reply->data,
                       im->result->reply->header->data_len - 1 -
                       sizeof (gint) - sizeof (gboolean));

  if (cursor_index)
  {
    *cursor_index = *(gint *) (im->result->reply->data +
                               im->result->reply->header->data_len -
                               sizeof (gint) - sizeof (gboolean));
  }

  return *(gboolean *) (im->result->reply->data - sizeof (gboolean));
}
Example #3
0
void dasom_im_reset (DasomIM *im)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  g_return_if_fail (DASOM_IS_IM (im));

  GSocket *socket = g_socket_connection_get_socket (im->connection);
  if (!socket || g_socket_is_closed (socket))
  {
    g_warning ("socket is closed");
    return;
  }

  dasom_send_message (socket, DASOM_MESSAGE_RESET, NULL, 0, NULL);
  dasom_result_iteration_until (im->result,
                                dasom_im_sockets_context,
                                DASOM_MESSAGE_RESET_REPLY);
}
Example #4
0
void dasom_im_set_use_preedit (DasomIM  *im,
                               gboolean  use_preedit)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  g_return_if_fail (DASOM_IS_IM (im));

  GSocket *socket = g_socket_connection_get_socket (im->connection);
  if (!socket || g_socket_is_closed (socket))
  {
    g_warning ("socket is closed");
    return;
  }

  dasom_send_message (socket, DASOM_MESSAGE_SET_USE_PREEDIT,
                      (gchar *) &use_preedit, sizeof (gboolean), NULL);
  dasom_result_iteration_until (im->result,
                                dasom_im_sockets_context,
                                DASOM_MESSAGE_SET_USE_PREEDIT_REPLY);
}
Example #5
0
void dasom_im_set_cursor_location (DasomIM              *im,
                                   const DasomRectangle *area)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  g_return_if_fail (DASOM_IS_IM (im));

  GSocket *socket = g_socket_connection_get_socket (im->connection);
  if (!socket || g_socket_is_closed (socket))
  {
    g_warning ("socket is closed");
    return;
  }

  dasom_send_message (socket, DASOM_MESSAGE_SET_CURSOR_LOCATION,
                      (gchar *) area, sizeof (DasomRectangle), NULL);
  dasom_result_iteration_until (im->result,
                                dasom_im_sockets_context,
                                DASOM_MESSAGE_SET_CURSOR_LOCATION_REPLY);
}
Example #6
0
gboolean dasom_im_filter_event (DasomIM *im, DasomEvent *event)
{
  g_debug (G_STRLOC ":%s", G_STRFUNC);

  g_return_val_if_fail (DASOM_IS_IM (im), FALSE);

  GSocket *socket = g_socket_connection_get_socket (im->connection);
  if (!socket || g_socket_is_closed (socket))
  {
    g_warning ("socket is closed");
    return dasom_im_filter_event_fallback (im, event);
  }

  dasom_send_message (socket, DASOM_MESSAGE_FILTER_EVENT, event,
                      sizeof (DasomEvent), NULL);
  dasom_result_iteration_until (im->result,
                                dasom_im_sockets_context,
                                DASOM_MESSAGE_FILTER_EVENT_REPLY);

  if (im->result->reply == NULL)
    return dasom_im_filter_event_fallback (im, event);

  return *(gboolean *) (im->result->reply->data);
}
Example #7
0
void dasom_im_set_surrounding (DasomIM    *im,
                               const char *text,
                               gint        len,
                               gint        cursor_index)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  g_return_if_fail (DASOM_IS_IM (im));

  GSocket *socket = g_socket_connection_get_socket (im->connection);
  if (!socket || g_socket_is_closed (socket))
  {
    g_warning ("socket is closed");
    return;
  }

  gchar *data = NULL;
  gint   str_len;

  if (len == -1)
    str_len = strlen (text);
  else
    str_len = len;

  data = g_strndup (text, str_len);
  data = g_realloc (data, str_len + 1 + 2 * sizeof (gint));

  *(gint *) (data + str_len + 1) = len;
  *(gint *) (data + str_len + 1 + sizeof (gint)) = cursor_index;

  dasom_send_message (socket, DASOM_MESSAGE_SET_SURROUNDING, data,
                      str_len + 1 + 2 * sizeof (gint), g_free);
  dasom_result_iteration_until (im->result,
                                dasom_im_sockets_context,
                                DASOM_MESSAGE_SET_SURROUNDING_REPLY);
}
Example #8
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;
}
Example #9
0
static void
dasom_im_init (DasomIM *im)
{
  g_debug (G_STRLOC ": %s", G_STRFUNC);

  GSocketClient  *client;
  GSocketAddress *address;
  GSocket        *socket;
  GError         *error = NULL;

  address = g_unix_socket_address_new_with_type (DASOM_ADDRESS, -1,
                                                 G_UNIX_SOCKET_ADDRESS_ABSTRACT);
  client = g_socket_client_new ();
  im->connection = g_socket_client_connect (client,
                                            G_SOCKET_CONNECTABLE (address),
                                            NULL, &error);
  g_object_unref (address);
  g_object_unref (client);

  if (im->connection == NULL)
  {
    g_critical (G_STRLOC ": %s: %s", G_STRFUNC, error->message);
    g_clear_error (&error);
    return;
  }

  socket = g_socket_connection_get_socket (im->connection);

  if (!socket)
  {
    g_critical (G_STRLOC ": %s: %s", G_STRFUNC, "Can't get socket");
    return;
  }

  DasomMessage *message;

  DasomConnectionType type = DASOM_CONNECTION_DASOM_IM;

  dasom_send_message (socket, DASOM_MESSAGE_CONNECT, &type, sizeof (DasomConnectionType), NULL);
  g_socket_condition_wait (socket, G_IO_IN, NULL, NULL);
  message = dasom_recv_message (socket);

  if (G_UNLIKELY (message == NULL ||
                  message->header->type != DASOM_MESSAGE_CONNECT_REPLY))
  {
    dasom_message_unref (message);
    g_error ("Couldn't connect to dasom daemon");
  }

  dasom_message_unref (message);

  im->result = g_slice_new0 (DasomResult);
  im->preedit_string = g_strdup ("");

  GMutex mutex;

  g_mutex_init (&mutex);
  g_mutex_lock (&mutex);

  if (G_UNLIKELY (dasom_im_sockets_context == NULL))
  {
    dasom_im_sockets_context = g_main_context_new ();
    dasom_im_sockets_context_ref_count++;
  }
  else
  {
    dasom_im_sockets_context = g_main_context_ref (dasom_im_sockets_context);
    dasom_im_sockets_context_ref_count++;
  }

  g_mutex_unlock (&mutex);

  /* when g_main_context_iteration(), iterate only sockets */
  im->sockets_context_source = g_socket_create_source (socket, G_IO_IN, NULL);
  g_source_set_can_recurse (im->sockets_context_source, TRUE);
  g_source_attach (im->sockets_context_source, dasom_im_sockets_context);
  g_source_set_callback (im->sockets_context_source,
                         (GSourceFunc) on_incoming_message,
                         im, NULL);

  im->default_context_source = g_socket_create_source (socket, G_IO_IN, NULL);
  g_source_set_can_recurse (im->default_context_source, TRUE);
  g_source_set_callback (im->default_context_source,
                         (GSourceFunc) on_incoming_message, im, NULL);
  g_source_attach (im->default_context_source, NULL);
}
Example #10
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;
}