1// LAF OS Library
2// Copyright (C) 2021 Igara Studio S.A.
3// Copyright (C) 2016 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef OS_X11_SYSTEM_H
9#define OS_X11_SYSTEM_H
10#pragma once
11
12#include "os/common/system.h"
13#include "os/x11/keys.h"
14#include "os/x11/screen.h"
15#include "os/x11/x11.h"
16
17namespace os {
18
19class SystemX11 : public CommonSystem {
20public:
21 ~SystemX11();
22
23 bool isKeyPressed(KeyScancode scancode) override {
24 return x11_is_key_pressed(scancode);
25 }
26
27 int getUnicodeFromScancode(KeyScancode scancode) override {
28 return x11_get_unicode_from_scancode(scancode);
29 }
30
31 CursorRef getNativeCursor(NativeCursor cursor);
32
33 CursorRef makeCursor(const Surface* surface,
34 const gfx::Point& focus,
35 const int scale) override;
36
37 gfx::Point mousePosition() const override {
38 int rootx, rooty, x, y;
39 unsigned int mask;
40 ::Display* display = X11::instance()->display();
41 ::Window root = XDefaultRootWindow(display);
42 ::Window child;
43 if (!XQueryPointer(display, root, &root, &child, &rootx, &rooty, &x, &y, &mask)) {
44 rootx = rooty = 0;
45 }
46 return gfx::Point(rootx, rooty);
47 }
48
49 void setMousePosition(const gfx::Point& screenPosition) override {
50 // TODO
51 }
52
53 gfx::Color getColorFromScreen(const gfx::Point& screenPosition) const override {
54#if 0
55 ::Display* display = X11::instance()->display();
56 int screen = XDefaultScreen(display);
57 ::Window root = XDefaultRootWindow(display);
58
59 // TODO XGetImage() crashes with a BadMatch error
60 XImage* image = XGetImage(display, root,
61 screenPosition.x,
62 screenPosition.y, 1, 1, AllPlanes, ZPixmap);
63 if (image) {
64 XColor color;
65 color.pixel = XGetPixel(image, screenPosition.x, screenPosition.y);
66 XFree(image);
67
68 XQueryColor(display, XDefaultColormap(display, screen), &color);
69
70 // Each red/green/blue channel is 16-bit, so we have to convert to 8-bit.
71 return gfx::rgba(color.red>>8, color.green>>8, color.blue>>8);
72 }
73 else
74#endif
75 return gfx::ColorNone;
76 }
77
78 ScreenRef mainScreen() override {
79 return make_ref<ScreenX11>(
80 XDefaultScreen(X11::instance()->display()));
81 }
82
83 void listScreens(ScreenList& list) override {
84 const int nscreen = XScreenCount(X11::instance()->display());
85 for (int screen=0; screen<nscreen; screen++)
86 list.push_back(make_ref<ScreenX11>(screen));
87 }
88
89};
90
91} // namespace os
92
93#endif
94