You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

150 lines
3.7 KiB

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