Exemple #1
0
static void i3ipc_con_initialize_floating_nodes(JsonArray *array, guint index_, JsonNode *element_node, gpointer user_data) {
  i3ipcCon *parent = I3IPC_CON(user_data);
  JsonObject *data = json_node_get_object(element_node);

  i3ipcCon *con = i3ipc_con_new(parent, data, parent->priv->conn);

  parent->priv->floating_nodes = g_list_append(parent->priv->floating_nodes, con);
}
/*
 * Callback function for when a channel receives data from the ipc socket.
 * Emits the corresponding signal with the reply.
 */
static gboolean ipc_on_data(GIOChannel *channel, GIOCondition condition, i3ipcConnection *conn) {
  if (condition != G_IO_IN)
    return TRUE;

  GIOStatus status;
  uint32_t reply_length;
  uint32_t reply_type;
  gchar *reply;
  GError *err = NULL;
  JsonParser *parser;
  JsonObject *json_reply;

  status = ipc_recv_message(channel, &reply_type, &reply_length, &reply, &err);

  if (status == G_IO_STATUS_EOF) {
    g_signal_emit(conn, connection_signals[IPC_SHUTDOWN], 0);

    if (conn->priv->main_loop != NULL)
      i3ipc_connection_main_quit(conn);

    return FALSE;
  }

  if (err) {
    g_warning("could not get event reply\n");
    g_error_free(err);
    g_free(reply);
    return TRUE;
  }

  reply[reply_length] = '\0';

  parser = json_parser_new();
  json_parser_load_from_data(parser, reply, -1, &err);

  if (err) {
    g_warning("could not parse event reply json (%s)\n", err->message);
    g_error_free(err);
    g_free(reply);
    g_object_unref(parser);
    return TRUE;
  }

  json_reply = json_node_get_object(json_parser_get_root(parser));

  switch (1 << (reply_type & 0x7F))
  {
    case I3IPC_EVENT_WORKSPACE:
      {
        i3ipcWorkspaceEvent *e = g_slice_new0(i3ipcWorkspaceEvent);

        e->change = g_strdup(json_object_get_string_member(json_reply, "change"));

        if (json_object_has_member(json_reply, "current") && !json_object_get_null_member(json_reply, "current"))
          e->current = i3ipc_con_new(NULL, json_object_get_object_member(json_reply, "current"), conn);

        if (json_object_has_member(json_reply, "old") && !json_object_get_null_member(json_reply, "old"))
          e->old = i3ipc_con_new(NULL, json_object_get_object_member(json_reply, "old"), conn);

        g_signal_emit(conn, connection_signals[WORKSPACE], g_quark_from_string(e->change), e);
        break;
      }

    case I3IPC_EVENT_OUTPUT:
      {
        i3ipcGenericEvent *e = g_slice_new0(i3ipcGenericEvent);

        e->change = g_strdup(json_object_get_string_member(json_reply, "change"));

        g_signal_emit(conn, connection_signals[OUTPUT], g_quark_from_string(e->change), e);
        break;
      }

    case I3IPC_EVENT_MODE:
      {
        i3ipcGenericEvent *e = g_slice_new0(i3ipcGenericEvent);

        e->change = g_strdup(json_object_get_string_member(json_reply, "change"));

        g_signal_emit(conn, connection_signals[MODE], g_quark_from_string(e->change), e);
        break;
      }

    case I3IPC_EVENT_WINDOW:
      {
        i3ipcWindowEvent *e = g_slice_new0(i3ipcWindowEvent);

        e->change = g_strdup(json_object_get_string_member(json_reply, "change"));

        if (json_object_has_member(json_reply, "container") && !json_object_get_null_member(json_reply, "container"))
          e->container = i3ipc_con_new(NULL, json_object_get_object_member(json_reply, "container"), conn);

        g_signal_emit(conn, connection_signals[WINDOW], g_quark_from_string(e->change), e);
        break;
      }

    case I3IPC_EVENT_BARCONFIG_UPDATE:
      {
        i3ipcBarconfigUpdateEvent *e = g_slice_new0(i3ipcBarconfigUpdateEvent);

        e->id = g_strdup(json_object_get_string_member(json_reply, "id"));
        e->hidden_state = g_strdup(json_object_get_string_member(json_reply, "hidden_state"));
        e->mode = g_strdup(json_object_get_string_member(json_reply, "mode"));

        g_signal_emit(conn, connection_signals[BARCONFIG_UPDATE], 0, e);
        break;
      }
    case I3IPC_EVENT_BINDING:
      {
        i3ipcBindingEvent *e = g_slice_new0(i3ipcBindingEvent);

        e->change = g_strdup(json_object_get_string_member(json_reply, "change"));

        JsonObject *json_binding_info = json_object_get_object_member(json_reply, "binding");
        e->binding = g_slice_new0(i3ipcBindingInfo);
        e->binding->command = g_strdup(json_object_get_string_member(json_binding_info, "command"));
        e->binding->input_code = json_object_get_int_member(json_binding_info, "input_code");
        e->binding->input_type = g_strdup(json_object_get_string_member(json_binding_info, "input_type"));
        e->binding->symbol = g_strdup(json_object_get_string_member(json_binding_info, "symbol"));

        JsonArray *mods = json_object_get_array_member(json_binding_info, "mods");
        gint mods_len = json_array_get_length(mods);

        for (int i = 0; i < mods_len; i += 1) {
          e->binding->mods = g_slist_append(e->binding->mods, g_strdup(json_array_get_string_element(mods, i)));
        }

        g_signal_emit(conn, connection_signals[BINDING], g_quark_from_string(e->change), e);
        break;
      }

    default:
      g_warning("got unknown event\n");
      break;
  }

  g_object_unref(parser);
  g_free(reply);

  return TRUE;
}