Logo Search packages:      
Sourcecode: acpid version File versions  Download package

acpid.c

#include <assert.h>

#include <dbus/dbus.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <syslog.h>

#include "acpi-watch.h"
#include "acpi-queue.h"

#include <acpid/driver.h>

static DBusConnection *conn;

static void dispatch(lua_State *L)
{
      struct acpi_channel_descriptor cds[12];
      unsigned long num = 0;

      lua_pushnil(L);
      while (lua_next(L, LUA_REGISTRYINDEX) != 0) {
            struct acpi_channel *channel = lua_touserdata(L, -2);
            num += (*channel->ops->setup)(channel, cds + num, 12 - num);

            lua_pop(L, 1);
            if (num == 12)
                  break;
      }

      lua_pop(L, 1);

      struct pollfd fds[num];
      for (unsigned long i = 0; i < num; ++i) {
            fds[i].fd = cds[i].fd;
            fds[i].events = cds[i].events;
      }

      int ret = poll(fds, num, -1);

      for (unsigned long i = 0; i < num; ++i) {
            if (fds[i].revents) {
                  int ret = (*cds[i].channel->ops->handle)(cds[i].channel, L, fds[i].fd, fds[i].revents); 
            }
      }
}

int acpi_dbus_event(const char *hid, unsigned long event, unsigned long data)
{
      DBusMessage *msg = dbus_message_new_signal("/org/kernel/acpi", "org.kernel.acpi.Event", "Broadcast");
      if (NULL == msg)
            exit(1);

      if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &hid, DBUS_TYPE_UINT32, &event, DBUS_TYPE_UINT32, &data, DBUS_TYPE_INVALID))
            exit(1);

      dbus_uint32_t serial = 0;
      if (!dbus_connection_send(conn, msg, &serial))
            exit(1);

      dbus_connection_flush(conn);
      dbus_message_unref(msg);

      return 0;
}

int main(int argc, char *argv[])
{
      DBusError err;
      dbus_error_init(&err);

      openlog("acpid-ng", 0, LOG_DAEMON);
      syslog(LOG_INFO, "starting\n");

      lua_State *L = luaL_newstate();
      luaL_dofile(L, "config.lua");

      lua_getfield(L, LUA_GLOBALSINDEX, "channels");
      lua_pushnil(L);

      while (lua_next(L, -2) != 0) {
            if (acpi_channel_create(L) == 0) {
                  lua_insert(L, -2);
                  lua_settable(L, LUA_REGISTRYINDEX);
            } else {
                  fprintf(stderr, "failed to create channel\n");
                  lua_pop(L, 1);
            }
      }

      lua_pop(L, 1);

      /* Remove the channel table */
      lua_pushnil(L);
      lua_setfield(L, LUA_GLOBALSINDEX, "channels");

      lua_createtable(L, 99, 0);
      lua_setfield(L, LUA_GLOBALSINDEX, "script");
      luaL_dofile(L, "scripts.lua");

      syslog(LOG_INFO, "loaded channels and scripts\n");

      /* At this point the lua stack should be empty! */
      assert(lua_gettop(L) == 0);

      conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
      if (conn == NULL) {
            fprintf(stderr, "Connection Error (%s)\n", err.message);
            dbus_error_free(&err);
            exit(1);
      }

      int ret = dbus_bus_request_name(conn, "org.kernel.acpi", DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
      if (dbus_error_is_set(&err)) {
            fprintf(stderr, "Name Error (%s)\n", err.message);
            dbus_error_free(&err);
            exit(1);
      }

      for (;;) {
            dispatch(L);

/*
            struct acpi_queue queue = { 0 };

            for (int i = 0; i < queue.num; ++i) {
                  printf("got an event from %s: %08x %08x %08x\n", queue.events[i].source, queue.events[i].type, queue.events[i].code, queue.events[i].value);

                  DBusMessage *msg = dbus_message_new_signal("/org/kernel/acpi", "org.kernel.acpi.Event", "Broadcast");
                  if (NULL == msg)
                        exit(1);

                  const char *source = queue.events[i].source;
                  if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &source, DBUS_TYPE_UINT32, &queue.events[i].type,
                        DBUS_TYPE_UINT32, &queue.events[i].code, DBUS_TYPE_UINT32, &queue.events[i].value, DBUS_TYPE_INVALID))
                        exit(1);

                  dbus_uint32_t serial = 0;
                  if (!dbus_connection_send(conn, msg, &serial))
                        exit(1);

                  dbus_connection_flush(conn);
                  dbus_message_unref(msg);
            }
*/
      }

      return 0;
}

Generated by  Doxygen 1.6.0   Back to index