123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- /* SLiM - Simple Login Manager
- Copyright (C) 2011 David Hauweele
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- */
- #include <cstdio>
- #include <iostream>
- #include <ck-connector.h>
- #include <X11/Xlib.h>
- #include <X11/Xatom.h>
- #include <stdarg.h>
- #include "Ck.h"
- namespace Ck {
- Exception::Exception(const std::string &func,
- const std::string &errstr):
- func(func),
- errstr(errstr)
- {}
- dbus_bool_t Session::ck_connector_open_graphic_session(const std::string &display,
- uid_t uid)
- {
- dbus_bool_t local = true;
- const char *session_type = "x11";
- const char *x11_display = display.c_str();
- const char *x11_device = get_x11_device(display);
- const char *remote_host = "";
- const char *display_dev = "";
- return ck_connector_open_session_with_parameters(ckc, &error,
- "unix-user", &uid,
- "session-type", &session_type,
- "x11-display", &x11_display,
- "x11-display-device", &x11_device,
- "display-device", &display_dev,
- "remote-host-name", &remote_host,
- "is-local", &local,
- NULL);
- }
- const char * Session::get_x11_device(const std::string &display)
- {
- static char device[32];
- Display *xdisplay = XOpenDisplay(display.c_str());
- if(!xdisplay)
- throw Exception(__func__, "cannot open display");
- Window root;
- Atom xfree86_vt_atom;
- Atom return_type_atom;
- int return_format;
- unsigned long return_count;
- unsigned long bytes_left;
- unsigned char *return_value;
- long vt;
- xfree86_vt_atom = XInternAtom(xdisplay, "XFree86_VT", true);
- if(xfree86_vt_atom == None)
- throw Exception(__func__, "cannot get XFree86_VT");
- root = DefaultRootWindow(xdisplay);
- if(XGetWindowProperty(xdisplay, root, xfree86_vt_atom,
- 0L, 1L, false, XA_INTEGER,
- &return_type_atom, &return_format,
- &return_count, &bytes_left,
- &return_value) != Success)
- throw Exception(__func__, "cannot get root window property");
- if(return_type_atom != XA_INTEGER)
- throw Exception(__func__, "bad atom type");
- if(return_format != 32)
- throw Exception(__func__, "invalid return format");
- if(return_count != 1)
- throw Exception(__func__, "invalid count");
- if(bytes_left != 0)
- throw Exception(__func__, "invalid bytes left");
- vt = *((long *)return_value);
- std::snprintf(device, 32, "/dev/tty%ld", vt);
- if(return_value)
- XFree(return_value);
- return device;
- }
- void Session::open_session(const std::string &display, uid_t uid)
- {
- ckc = ck_connector_new();
- if(!ckc)
- throw Exception(__func__, "error setting up connection to ConsoleKit");
- if(!ck_connector_open_graphic_session(display, uid)) {
- if(dbus_error_is_set(&error))
- throw Exception(__func__, error.message);
- else
- throw Exception(__func__, "cannot open ConsoleKit session: OOM, DBus system bus "
- " not available or insufficient privileges");
- }
- }
- const char * Session::get_xdg_session_cookie()
- {
- return ck_connector_get_cookie(ckc);
- }
- void Session::close_session()
- {
- if(!ck_connector_close_session(ckc, &error)) {
- if(dbus_error_is_set(&error))
- throw Exception(__func__, error.message);
- else
- throw Exception(__func__, "cannot close ConsoleKit session: OOM, DBus system bus "
- " not available or insufficient privileges");
- }
- }
- Session::Session()
- {
- dbus_error_init(&error);
- }
- Session::~Session()
- {
- dbus_error_free(&error);
- }
- };
- std::ostream& operator<<( std::ostream& os, const Ck::Exception& e)
- {
- os << e.func << ": " << e.errstr;
- return os;
- }
|