Commit initial
This commit is contained in:
commit
69b2cb0def
49
src/Exception.cpp
Normal file
49
src/Exception.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include "Exception.hpp"
|
||||
|
||||
|
||||
Kronos::Exception::Exception::Exception() : m_cause(nullptr) {
|
||||
initTrace();
|
||||
}
|
||||
|
||||
Kronos::Exception::Exception::Exception(const std::string& message) : m_cause(nullptr), m_message(message) {
|
||||
initTrace();
|
||||
}
|
||||
|
||||
Kronos::Exception::Exception::Exception(const std::string& message, const std::exception& cause) : m_cause(&cause), m_message(message) {
|
||||
initTrace();
|
||||
}
|
||||
|
||||
Kronos::Exception::Exception::Exception(const std::exception& cause) : m_cause(&cause) {
|
||||
initTrace();
|
||||
}
|
||||
|
||||
void Kronos::Exception::Exception::initTrace() {
|
||||
std::stringstream ss;
|
||||
|
||||
const std::string& msg = getMessage();
|
||||
|
||||
ss << typeid(*this).name();
|
||||
if(!msg.empty()) {
|
||||
ss << " : " << msg;
|
||||
}
|
||||
if(m_cause != nullptr) {
|
||||
ss << "\n -> " << m_cause->what();
|
||||
}
|
||||
|
||||
m_trace = ss.str();
|
||||
}
|
||||
|
||||
const char* Kronos::Exception::Exception::what() const noexcept {
|
||||
return m_trace.c_str();
|
||||
}
|
||||
|
||||
const std::exception* Kronos::Exception::Exception::getCause() const {
|
||||
return m_cause;
|
||||
}
|
||||
|
||||
const std::string& Kronos::Exception::Exception::getMessage() const {
|
||||
return m_message;
|
||||
}
|
31
src/Exception.hpp
Normal file
31
src/Exception.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef KRONOS_EXCEPTION_HEADER
|
||||
#define KRONOS_EXCEPTION_HEADER
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Kronos {
|
||||
namespace Exception {
|
||||
class Exception : public std::exception {
|
||||
private:
|
||||
const std::exception* m_cause;
|
||||
const std::string m_message;
|
||||
std::string m_trace;
|
||||
|
||||
void initTrace();
|
||||
|
||||
public:
|
||||
Exception();
|
||||
Exception(const std::string& message);
|
||||
Exception(const std::exception& cause);
|
||||
Exception(const std::string& message, const std::exception& cause);
|
||||
|
||||
const char* what() const noexcept;
|
||||
const std::exception* getCause() const;
|
||||
virtual const std::string& getMessage() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
15
src/IOException.hpp
Normal file
15
src/IOException.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef KRONOS_IOEXCEPTION_HEADER
|
||||
#define KRONOS_IOEXCEPTION_HEADER
|
||||
|
||||
#include "Exception.hpp"
|
||||
|
||||
|
||||
namespace Kronos {
|
||||
namespace Exception {
|
||||
class IOException : public Exception {
|
||||
using Exception::Exception;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
76
src/Logger.cpp
Normal file
76
src/Logger.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "IOException.hpp"
|
||||
#include "Logger.hpp"
|
||||
|
||||
|
||||
Kronos::Logger* Kronos::Logger::s_instance = nullptr;
|
||||
|
||||
void Kronos::Logger::Log(const std::string& msg) {
|
||||
Kronos::Logger::Log(Kronos::Logger::Level::INFO, msg);
|
||||
}
|
||||
|
||||
void Kronos::Logger::Log(Kronos::Logger::Level level, const std::string& msg) {
|
||||
assert(Kronos::Logger::s_instance != nullptr);
|
||||
Kronos::Logger::s_instance->log(level, msg);
|
||||
}
|
||||
|
||||
Kronos::Logger::Logger(Kronos::Logger::Level level, const char* filename, bool console)
|
||||
: m_level(level), m_console(console) {
|
||||
assert(Kronos::Logger::s_instance == nullptr);
|
||||
|
||||
if(filename != nullptr) {
|
||||
m_logFile.open(filename, std::ofstream::app);
|
||||
if(!m_logFile.is_open()) {
|
||||
throw Kronos::Exception::IOException("Unable to open log file <" + std::string(filename) + ">");
|
||||
}
|
||||
}
|
||||
|
||||
Kronos::Logger::s_instance = this;
|
||||
}
|
||||
|
||||
Kronos::Logger::~Logger() {
|
||||
if(m_logFile.is_open()) {
|
||||
m_logFile.close();
|
||||
}
|
||||
Kronos::Logger::s_instance = nullptr;
|
||||
}
|
||||
|
||||
void Kronos::Logger::setLevel(Kronos::Logger::Level level) {
|
||||
m_level = level;
|
||||
}
|
||||
|
||||
void Kronos::Logger::log(Kronos::Logger::Level level, const std::string& msg) {
|
||||
if(level <= m_level) {
|
||||
time_t curTime = time(nullptr);
|
||||
std::stringstream ss;
|
||||
|
||||
char dtStr[20];
|
||||
strftime(dtStr, 20, "%Y-%m-%d %H:%M:%S", localtime(&curTime));
|
||||
|
||||
const char* lvlName = nullptr;
|
||||
if(level == Kronos::Logger::Level::ERROR) {
|
||||
lvlName = "ERROR";
|
||||
} else if(level == Kronos::Logger::Level::WARN) {
|
||||
lvlName = "WARN";
|
||||
} else if(level == Kronos::Logger::Level::DEBUG) {
|
||||
lvlName = "DEBUG";
|
||||
} else {
|
||||
lvlName = "INFO";
|
||||
}
|
||||
|
||||
ss << "[" << dtStr << "]" << "[" << lvlName << "] : " << msg;
|
||||
|
||||
if(m_logFile.is_open()) {
|
||||
m_logFile << ss.str() << std::endl;
|
||||
}
|
||||
|
||||
if(m_console) {
|
||||
std::cout << ss.str() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
35
src/Logger.hpp
Normal file
35
src/Logger.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef KRONOS_LOGGER_HEADER
|
||||
#define KRONOS_LOGGER_HEADER
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Kronos {
|
||||
class Logger final {
|
||||
public:
|
||||
enum Level {ERROR = 0, WARN = 1, INFO = 2, DEBUG = 3};
|
||||
|
||||
static void Log(const std::string& msg);
|
||||
static void Log(Level level, const std::string& msg);
|
||||
|
||||
Logger(Level level = Level::INFO, const char* filename = nullptr, bool console = true);
|
||||
Logger(const Logger& logger) = delete;
|
||||
~Logger();
|
||||
|
||||
Logger& operator=(const Logger& logger) = delete;
|
||||
|
||||
void setLevel(Level level);
|
||||
|
||||
private:
|
||||
void log(Level level, const std::string& msg);
|
||||
|
||||
static Logger* s_instance;
|
||||
|
||||
Level m_level;
|
||||
std::ofstream m_logFile;
|
||||
bool m_console;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
33
src/Makefile
Normal file
33
src/Makefile
Normal file
@ -0,0 +1,33 @@
|
||||
.PHONY: clean
|
||||
CXX=g++
|
||||
CXXFLAGS_DEBUG:=$(CXXFLAGS) -Wall -std=c++17 -g
|
||||
CXXFLAGS:=$(CXXFLAGS) -Wall -std=c++17 -O2 -s
|
||||
LDFLAGS:=$(LDFLAGS)
|
||||
INC_CXXFLAGS=
|
||||
LIBS=-lX11
|
||||
|
||||
TARGETS=kronos
|
||||
TARGETS_DEBUG=kronos_dbg
|
||||
SRC=main.cpp Exception.cpp Logger.cpp XDisplayConnection.cpp XWindow.cpp
|
||||
OBJ=$(SRC:.cpp=.o)
|
||||
OBJ_DEBUG=$(SRC:.cpp=.odbg)
|
||||
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
debug: $(TARGETS_DEBUG)
|
||||
|
||||
kronos: $(OBJ)
|
||||
$(CXX) $(LDFLAGS) $(LIBS) $^ -o $@
|
||||
|
||||
kronos_dbg: $(OBJ_DEBUG)
|
||||
$(CXX) $(LDFLAGS) $(LIBS) $^ -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CXXFLAGS) $(INC_CXXFLAGS) -c $^ -o $@
|
||||
|
||||
%.odbg: %.cpp
|
||||
$(CXX) $(CXXFLAGS_DEBUG) $(INC_CXXFLAGS) -c $^ -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS) $(TARGETS_DEBUG) $(OBJ) $(OBJ_DEBUG)
|
13
src/WindowRecorder.hpp
Normal file
13
src/WindowRecorder.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef WINDOW_RECORDER_HEADER
|
||||
#define WINDOW_RECORDER_HEADER
|
||||
|
||||
namespace Kronos {
|
||||
class WindowRecorder {
|
||||
public:
|
||||
virtual ~WindowRecorder() = 0;
|
||||
|
||||
virtual prepare
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
45
src/XDisplayConnection.cpp
Normal file
45
src/XDisplayConnection.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include "Logger.hpp"
|
||||
#include "XWindow.hpp"
|
||||
#include "XDisplayInitException.hpp"
|
||||
#include "XDisplayConnection.hpp"
|
||||
|
||||
|
||||
Kronos::XDisplayConnection::XDisplayConnection(const char* name) {
|
||||
m_display = XOpenDisplay(name);
|
||||
if(m_display == nullptr) {
|
||||
throw Kronos::Exception::XDisplayInitException("Unable to open X display");
|
||||
}
|
||||
}
|
||||
|
||||
Kronos::XDisplayConnection::~XDisplayConnection() {
|
||||
XCloseDisplay(m_display);
|
||||
}
|
||||
|
||||
Display* Kronos::XDisplayConnection::getDisplay() {
|
||||
return m_display;
|
||||
}
|
||||
|
||||
std::vector<Kronos::XWindow> Kronos::XDisplayConnection::getWindows() {
|
||||
std::vector<XWindow> windows;
|
||||
Atom propWin = XInternAtom(m_display, "_NET_CLIENT_LIST", False);
|
||||
Atom type;
|
||||
int form;
|
||||
unsigned long remain, len;
|
||||
unsigned char* prop = nullptr;
|
||||
|
||||
if(XGetWindowProperty(m_display, XDefaultRootWindow(m_display), propWin, 0, 1024, False, XA_WINDOW, &type, &form, &len, &remain, &prop) == Success) {
|
||||
Window* wins = (Window*) prop;
|
||||
for(unsigned long i = 0; i < len; i++) {
|
||||
windows.push_back(Kronos::XWindow(*this, wins[i]));
|
||||
}
|
||||
XFree(prop);
|
||||
} else {
|
||||
Kronos::Logger::Log(Kronos::Logger::Level::ERROR, "Unable to get windows list from XGetWindowProperty");
|
||||
}
|
||||
|
||||
return windows;
|
||||
}
|
26
src/XDisplayConnection.hpp
Normal file
26
src/XDisplayConnection.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef KRONOS_XDISPLAY_CONNECTION_HEADER
|
||||
#define KRONOS_XDISPLAY_CONNECTION_HEADER
|
||||
|
||||
#include <vector>
|
||||
#include <X11/Xlib.h>
|
||||
#include "XWindow.hpp"
|
||||
|
||||
|
||||
namespace Kronos {
|
||||
class XDisplayConnection {
|
||||
public:
|
||||
XDisplayConnection(const char* name = nullptr);
|
||||
XDisplayConnection(const XDisplayConnection& conn) = delete;
|
||||
~XDisplayConnection();
|
||||
|
||||
XDisplayConnection& operator=(const XDisplayConnection& conn) = delete;
|
||||
|
||||
Display* getDisplay();
|
||||
std::vector<XWindow> getWindows();
|
||||
|
||||
private:
|
||||
Display* m_display;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
15
src/XDisplayInitException.hpp
Normal file
15
src/XDisplayInitException.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef KRONOS_XDISPLAYINITEXCEPTION_HEADER
|
||||
#define KRONOS_XDISPLAYINITEXCEPTION_HEADER
|
||||
|
||||
#include "Exception.hpp"
|
||||
|
||||
|
||||
namespace Kronos {
|
||||
namespace Exception {
|
||||
class XDisplayInitException : public Exception {
|
||||
using Exception::Exception;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
63
src/XWindow.cpp
Normal file
63
src/XWindow.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <string>
|
||||
#include "XDisplayConnection.hpp"
|
||||
#include "XWindowInitException.hpp"
|
||||
#include "XWindow.hpp"
|
||||
|
||||
|
||||
Kronos::XWindow::XWindow(Kronos::XDisplayConnection& conn, Window window)
|
||||
: m_conn(conn), m_window(window) {
|
||||
Atom propName = XInternAtom(m_conn.getDisplay(), "WM_NAME", False);
|
||||
Atom type;
|
||||
int form;
|
||||
unsigned long remain, len;
|
||||
unsigned char* prop = nullptr;
|
||||
|
||||
if(XGetWindowProperty(m_conn.getDisplay(), m_window, propName, 0, 1024, False, AnyPropertyType, &type, &form, &len, &remain, &prop) == Success) {
|
||||
m_name = (const char*) prop;
|
||||
XFree(prop);
|
||||
}
|
||||
|
||||
XWindowAttributes attr;
|
||||
if(!XGetWindowAttributes(m_conn.getDisplay(), m_window, &attr)) {
|
||||
throw Kronos::Exception::XWindowInitException();
|
||||
}
|
||||
m_width = attr.width;
|
||||
m_height = attr.height;
|
||||
|
||||
XSelectInput(m_conn.getDisplay(), m_window, StructureNotifyMask);
|
||||
XSync(m_conn.getDisplay(), 0);
|
||||
}
|
||||
|
||||
Kronos::XWindow::~XWindow() {
|
||||
XSelectInput(m_conn.getDisplay(), m_window, 0);
|
||||
}
|
||||
|
||||
void Kronos::XWindow::processEvents() {
|
||||
/*
|
||||
* IT DOES'T WORK !!
|
||||
*/
|
||||
|
||||
while(XEventsQueued(m_conn.getDisplay(), QueuedAfterReading) > 0) {
|
||||
XEvent event;
|
||||
XNextEvent(m_conn.getDisplay(), &event);
|
||||
if(event.type == ConfigureNotify) {
|
||||
XConfigureEvent conf = event.xconfigure;
|
||||
m_width = conf.width;
|
||||
m_height = conf.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string Kronos::XWindow::getName() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
int Kronos::XWindow::getWidth() const {
|
||||
return m_width;
|
||||
}
|
||||
|
||||
int Kronos::XWindow::getHeight() const {
|
||||
return m_height;
|
||||
}
|
31
src/XWindow.hpp
Normal file
31
src/XWindow.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef KRONOS_XWINDOW_HEADER
|
||||
#define KRONOS_XWINDOW_HEADER
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <string>
|
||||
//#include "XDisplayConnection.hpp"
|
||||
|
||||
|
||||
namespace Kronos {
|
||||
class XDisplayConnection;
|
||||
|
||||
class XWindow {
|
||||
public:
|
||||
XWindow(XDisplayConnection& conn, Window window);
|
||||
~XWindow();
|
||||
|
||||
void processEvents();
|
||||
std::string getName() const;
|
||||
int getWidth() const;
|
||||
int getHeight() const;
|
||||
|
||||
private:
|
||||
XDisplayConnection& m_conn;
|
||||
Window m_window;
|
||||
std::string m_name;
|
||||
int m_width;
|
||||
int m_height;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
15
src/XWindowInitException.hpp
Normal file
15
src/XWindowInitException.hpp
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef KRONOS_XWINDOWINITEXCEPTION_HEADER
|
||||
#define KRONOS_XWINDOWINITEXCEPTION_HEADER
|
||||
|
||||
#include "Exception.hpp"
|
||||
|
||||
|
||||
namespace Kronos {
|
||||
namespace Exception {
|
||||
class XWindowInitException : public Exception {
|
||||
using Exception::Exception;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
23
src/main.cpp
Normal file
23
src/main.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "Exception.hpp"
|
||||
#include "Logger.hpp"
|
||||
#include "XDisplayConnection.hpp"
|
||||
#include "XWindow.hpp"
|
||||
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Kronos::Logger logger(Kronos::Logger::Level::INFO, "kronos.log");
|
||||
Kronos::Logger::Log("=============== Kronos v0.1 ===============");
|
||||
|
||||
Kronos::XDisplayConnection display;
|
||||
std::vector<Kronos::XWindow> windows = display.getWindows();
|
||||
|
||||
for(Kronos::XWindow& w : windows) {
|
||||
w.processEvents();
|
||||
std::cout << "=> " << w.getName() << std::endl;
|
||||
std::cout << " - " << w.getWidth() << "x" << w.getHeight() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user