Ck.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /* SLiM - Simple Login Manager
  2. * Copyright (C) 2011 David Hauweele
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #include <cstdio>
  10. #include <iostream>
  11. #include <ck-connector.h>
  12. #include <X11/Xlib.h>
  13. #include <X11/Xatom.h>
  14. #include <stdarg.h>
  15. #include "Ck.h"
  16. namespace Ck {
  17. Exception::Exception(const std::string &func,
  18. const std::string &errstr):
  19. func(func),
  20. errstr(errstr)
  21. {}
  22. dbus_bool_t
  23. Session::ck_connector_open_graphic_session(
  24. const std::string &display,
  25. uid_t uid)
  26. {
  27. dbus_bool_t local = true;
  28. const char *session_type = "x11";
  29. const char *x11_display = display.c_str();
  30. const char *x11_device = get_x11_device(display);
  31. const char *remote_host = "";
  32. const char *display_dev = "";
  33. return ck_connector_open_session_with_parameters(ckc, &error,
  34. "unix-user", &uid,
  35. "session-type", &session_type,
  36. "x11-display", &x11_display,
  37. "x11-display-device", &x11_device,
  38. "display-device", &display_dev,
  39. "remote-host-name", &remote_host,
  40. "is-local", &local,
  41. NULL);
  42. }
  43. const char * Session::get_x11_device(const std::string &display)
  44. {
  45. static char device[32];
  46. Display *xdisplay = XOpenDisplay(display.c_str());
  47. if(!xdisplay)
  48. throw Exception(__func__, "cannot open display");
  49. Window root;
  50. Atom xfree86_vt_atom;
  51. Atom return_type_atom;
  52. int return_format;
  53. unsigned long return_count;
  54. unsigned long bytes_left;
  55. unsigned char *return_value;
  56. long vt;
  57. xfree86_vt_atom = XInternAtom(xdisplay, "XFree86_VT", true);
  58. if(xfree86_vt_atom == None)
  59. throw Exception(__func__, "cannot get XFree86_VT");
  60. root = DefaultRootWindow(xdisplay);
  61. if(XGetWindowProperty(xdisplay, root, xfree86_vt_atom,
  62. 0L, 1L, false, XA_INTEGER,
  63. &return_type_atom, &return_format,
  64. &return_count, &bytes_left,
  65. &return_value) != Success)
  66. throw Exception(__func__, "cannot get root window property");
  67. if(return_type_atom != XA_INTEGER)
  68. throw Exception(__func__, "bad atom type");
  69. if(return_format != 32)
  70. throw Exception(__func__, "invalid return format");
  71. if(return_count != 1)
  72. throw Exception(__func__, "invalid count");
  73. if(bytes_left != 0)
  74. throw Exception(__func__, "invalid bytes left");
  75. vt = *((long *)return_value);
  76. std::snprintf(device, 32, "/dev/tty%ld", vt);
  77. if(return_value)
  78. XFree(return_value);
  79. return device;
  80. }
  81. void Session::open_session(const std::string &display, uid_t uid)
  82. {
  83. ckc = ck_connector_new();
  84. if(!ckc)
  85. throw Exception(__func__, "error setting up connection to ConsoleKit");
  86. if (!ck_connector_open_graphic_session(display, uid)) {
  87. if(dbus_error_is_set(&error))
  88. throw Exception(__func__, error.message);
  89. else
  90. throw Exception(__func__, "cannot open ConsoleKit session: OOM,"
  91. " DBus system bus not available or insufficient"
  92. " privileges");
  93. }
  94. }
  95. const char * Session::get_xdg_session_cookie()
  96. {
  97. return ck_connector_get_cookie(ckc);
  98. }
  99. void Session::close_session()
  100. {
  101. if(!ck_connector_close_session(ckc, &error)) {
  102. if(dbus_error_is_set(&error))
  103. throw Exception(__func__, error.message);
  104. else
  105. throw Exception(__func__, "cannot close ConsoleKit session: OOM,"
  106. " DBus system bus not available or insufficient"
  107. " privileges");
  108. }
  109. }
  110. Session::Session()
  111. {
  112. dbus_error_init(&error);
  113. }
  114. Session::~Session()
  115. {
  116. dbus_error_free(&error);
  117. }
  118. }
  119. std::ostream& operator<<( std::ostream& os, const Ck::Exception& e)
  120. {
  121. os << e.func << ": " << e.errstr;
  122. return os;
  123. }