forked from MrBesen/lolautoaccept
140 lines
3.6 KiB
C++
140 lines
3.6 KiB
C++
// g++ screena.cpp -o screena -lX11 -lXext -Ofast -mfpmath=both -march=native -m64 -funroll-loops -mavx2 `pkg-config opencv --cflags --libs` && ./screena
|
|
|
|
// This includes most headers!
|
|
|
|
#include "screen.h"
|
|
|
|
#include <X11/cursorfont.h>
|
|
#include <Log.h>
|
|
|
|
const uint32_t ScreenShot::DEFAULTWIDTH = 1280;
|
|
const uint32_t ScreenShot::DEFAULTHEIGHT = 720;
|
|
|
|
// https://stackoverflow.com/a/39781697/4399859
|
|
|
|
static void searchWindows(Display* disp, Window top, const std::string& search, std::vector<Window>& result) {
|
|
|
|
char* window_name;
|
|
if (XFetchName(disp, top, &window_name)) {
|
|
if (search == window_name) {
|
|
result.push_back(top);
|
|
return; // dont look for kids
|
|
}
|
|
}
|
|
|
|
Window* children = nullptr, dummy;
|
|
unsigned int nchildren;
|
|
if (!XQueryTree(disp, top, &dummy, &dummy, &children, &nchildren))
|
|
return;
|
|
|
|
for (unsigned int i = 0; i < nchildren; i++) {
|
|
searchWindows(disp, children[i], search, result);
|
|
}
|
|
if (children)
|
|
XFree((char*) children);
|
|
}
|
|
|
|
std::vector<ScreenShot*> ScreenShot::getWindows(const std::string& name) {
|
|
Display* display = XOpenDisplay(nullptr);
|
|
|
|
Log::info << "searching for: " << name;
|
|
|
|
std::vector<Window> list;
|
|
searchWindows(display, DefaultRootWindow(display), name, list);
|
|
std::vector<ScreenShot*> out;
|
|
|
|
out.reserve(list.size());
|
|
for (Window w : list) {
|
|
ScreenShot* ss = new ScreenShot(display, w);
|
|
if(ss->valid)
|
|
out.push_back(ss);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
bool ScreenShot::updateAttrib() {
|
|
Status attrb = XGetWindowAttributes(display, window, &wattrib);
|
|
|
|
if (attrb == BadWindow || attrb == BadDrawable) {
|
|
Log::error << "XGetWindowAttributes() falied";
|
|
return false;
|
|
}
|
|
|
|
if((wattrib.c_class != InputOutput) || (wattrib.map_state != IsViewable)) {
|
|
Log::warn << "Window is not viewable - window class: " << wattrib.c_class << " map state: " << wattrib.map_state << " - ignoring window";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ScreenShot::initImg() {
|
|
bool upd = updateAttrib();
|
|
if(!upd) return false;
|
|
|
|
char* wname = nullptr;
|
|
XFetchName(display, window, &wname);
|
|
if (wname)
|
|
windowname = std::string(wname);
|
|
|
|
Log::info << "Window " << std::quoted(windowname) << " x: " << wattrib.x << " y: " << wattrib.y << " w: " << wattrib.width << " h: " << wattrib.height;
|
|
|
|
ximg = XShmCreateImage(display, wattrib.visual, wattrib.depth, ZPixmap, NULL, &shminfo, wattrib.width, wattrib.height);
|
|
|
|
shminfo.shmid = shmget(IPC_PRIVATE, ximg->bytes_per_line * ximg->height, IPC_CREAT | 0777);
|
|
shminfo.shmaddr = ximg->data = (char*) shmat(shminfo.shmid, 0, 0);
|
|
shminfo.readOnly = false;
|
|
if (shminfo.shmid < 0)
|
|
Log::fatal << "Fatal shminfo error!";
|
|
Status s1 = XShmAttach(display, &shminfo);
|
|
Log::info << "XShmAttach() " << (s1 ? "success!" : "failure!");
|
|
|
|
init = true;
|
|
return true;
|
|
}
|
|
|
|
ScreenShot::ScreenShot() {
|
|
|
|
display = XOpenDisplay(nullptr);
|
|
window = DefaultRootWindow(display);
|
|
|
|
int count_screens = ScreenCount(display);
|
|
if (count_screens == 0) {
|
|
puts("no screen info!");
|
|
}
|
|
for (int i = 0; i < count_screens; ++i) {
|
|
Screen* screen = ScreenOfDisplay(display, i);
|
|
printf("\tScreen %d: %dX%d\n", i + 1, screen->width, screen->height);
|
|
}
|
|
|
|
valid = initImg();
|
|
}
|
|
|
|
ScreenShot::ScreenShot(Display* d, Window w) : display(d), window(w), closeDisp(false) {
|
|
valid = initImg();
|
|
}
|
|
|
|
void ScreenShot::take(cv::Mat& cv_img) {
|
|
if (init)
|
|
init = false;
|
|
|
|
XShmGetImage(display, window, ximg, 0, 0, 0x00ffffff);
|
|
cv_img = cv::Mat(wattrib.height, wattrib.width, CV_8UC4, ximg->data);
|
|
}
|
|
|
|
void ScreenShot::operator() (cv::Mat& cv_img) {
|
|
take(cv_img);
|
|
}
|
|
|
|
ScreenShot::~ScreenShot() {
|
|
if (!init)
|
|
XDestroyImage(ximg);
|
|
|
|
XShmDetach(display, &shminfo);
|
|
shmdt(shminfo.shmaddr);
|
|
|
|
if (closeDisp)
|
|
XCloseDisplay(display);
|
|
}
|