suckless-utils/slim/Ck.cpp
Alexis Jhon Gaspar e1207e1d0d Added slim-fork to the repo
- This introduces a minimalist display manager for the suckless-utils suite
- Added crudely written scripts for reloaading slim's theme via pywal,
  meaning no on-the-fly reloading using keybinds as nost people wouldn't
have their sudo passwordless
- This is based on slim-fork 1.4.0 version.
2023-10-12 23:08:23 +08:00

153 lines
3.6 KiB
C++

/* 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::sprintf(device, "/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;
}