JeVois  1.22
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
VideoDisplayBackendX11.C
Go to the documentation of this file.
1// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2020 by Laurent Itti, the University of Southern
4// California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5//
6// This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7// redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8// Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10// License for more details. You should have received a copy of the GNU General Public License along with this program;
11// if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12//
13// Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14// Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16/*! \file */
17
18#ifdef JEVOIS_HOST_PRO
19
21
22// Restore None, etc as defined by X11/X.h as we need it here, and only here. See OpenGL.H for what we undef:
23#ifndef None
24#define None 0L
25#endif
26
27#ifndef Status
28#define Status int
29#endif
30
31#ifndef Success
32#define Success 0
33#endif
34
35#include <X11/Xlib.h>
36#include <X11/Xatom.h>
37#include <X11/Xutil.h>
38#include <X11/extensions/dpms.h>
39// ##############################################################################################################
40class jevois::VideoDisplayBackendX11::Impl
41{
42 public:
43 // On host, use an X11 window:
44 Display *itsX11display = nullptr;
45 Window itsWindow = 0;
46};
47
48// ##############################################################################################################
49jevois::VideoDisplayBackendX11::VideoDisplayBackendX11() :
50 jevois::VideoDisplayBackend(), pimpl(new Impl)
51{ }
52
53// ##############################################################################################################
54jevois::VideoDisplayBackendX11::~VideoDisplayBackendX11()
55{
56 // It is better to call uninit() explicitly from the same thread that called init() and others, but just in case:
57 uninit();
58}
59
60// ##############################################################################################################
61void jevois::VideoDisplayBackendX11::init(unsigned short w, unsigned short h, bool fullscreen)
62{
63 // Open the default display:
64 pimpl->itsX11display = XOpenDisplay(NULL);
65 if (pimpl->itsX11display == nullptr) LFATAL("Cannot open X11 display");
66
67 // Access to the top level window:
68 Window win_root = DefaultRootWindow(pimpl->itsX11display);
69
70 // Allow the window manager to control the window that will be created:
71 XSetWindowAttributes xattr { };
72 xattr.override_redirect = false;
73
74 // Announce events when the keyboard is pressed or the window state changes:
75 xattr.event_mask = ExposureMask | KeyPressMask;
76
77 // Set the background to white, making it clear when X has the window cleared:
78 xattr.background_pixel = XWhitePixel(pimpl->itsX11display, XDefaultScreen(pimpl->itsX11display));
79
80 // create the native window based on the attributes selected an resolution passed in.
81 pimpl->itsWindow = XCreateWindow(pimpl->itsX11display, win_root, 0, 0, w, h, 0,
82 CopyFromParent, InputOutput, CopyFromParent,
83 CWOverrideRedirect | CWEventMask | CWBackPixel, &xattr);
84
85 // Set the window properties:
86 XSetStandardProperties(pimpl->itsX11display, pimpl->itsWindow, itsName.c_str(), itsName.c_str(), None, NULL, 0, NULL);
87
88 // Disable the display power management to turn keep the display on:
89 DPMSDisable(pimpl->itsX11display);
90
91 // Set the window to the background pixel and display it to the front:
92 XClearWindow(pimpl->itsX11display, pimpl->itsWindow);
93 XMapRaised (pimpl->itsX11display, pimpl->itsWindow);
94
95 // Optionally request that the window becomes full screen and borderless. It will take some time for the display to
96 // acknowledge the event. An Expose event will occur when this is completed:
97 if (fullscreen)
98 {
99 Atom wm_state = XInternAtom(pimpl->itsX11display, "_NET_WM_STATE", false);
100 Atom fs = XInternAtom(pimpl->itsX11display, "_NET_WM_STATE_FULLSCREEN", false);
101
102 XEvent fs_event { };
103 fs_event.type = ClientMessage;
104 fs_event.xclient.window = pimpl->itsWindow;
105 fs_event.xclient.message_type = wm_state;
106 fs_event.xclient.format = 32;
107 fs_event.xclient.data.l[0] = 1;
108 fs_event.xclient.data.l[1] = fs;
109 fs_event.xclient.data.l[2] = 0;
110
111 XSendEvent(pimpl->itsX11display, win_root, false, SubstructureRedirectMask | SubstructureNotifyMask, &fs_event);
112 }
113
114 // Initialize OpenGL. Will turn itsDisplayReady to true:
115 jevois::VideoDisplayBackend::init(w, h, (EGLNativeWindowType)(pimpl->itsWindow));
116}
117
118// ##############################################################################################################
119void jevois::VideoDisplayBackendX11::uninit()
120{
121 if (pimpl->itsX11display)
122 {
123 // Turn display power management back on:
124 DPMSEnable(pimpl->itsX11display);
125
126 // Close the application window and release display handle::
127 if (pimpl->itsWindow) { XDestroyWindow(pimpl->itsX11display, pimpl->itsWindow); pimpl->itsWindow = 0; }
128 XCloseDisplay(pimpl->itsX11display); pimpl->itsX11display = nullptr;
129 }
130
131 // ALso close OpenGL using our base class:
133}
134
135// ##############################################################################################################
136bool jevois::VideoDisplayBackendX11::pollEvents(bool & shouldclose)
137{
138 XEvent event;
139 bool gotsome = false;
140
141 // Process events, one at a time, until there are none remaining:
142 while (XPending(pimpl->itsX11display))
143 {
144 gotsome = true;
145
146 XNextEvent(pimpl->itsX11display, &event);
147 switch (event.type)
148 {
149 case Expose:
150 // Window resized/hidden/shown etc. ignored as we will refresh soon anyway.
151 break;
152
153 case KeyPress:
154 {
155 // Keyboard events occured, get the key sequence, limit to 10 keys total:
156 char text[11]; KeySym key_press;
157 int keys = XLookupString(&event.xkey, text, 10, &key_press, 0);
158 if (keys == 1 && text[0] == 'q') shouldclose = true;
159 break;
160 }
161
162 default: break;
163 }
164 }
165
166 return gotsome;
167}
168
169#endif // JEVOIS_HOST_PRO
int h
Definition GUIhelper.C:2520
virtual void uninit()
Un-initialize the underlying engine, close windows, etc.
virtual void init(unsigned short w, unsigned short h, bool fullscreen=false)=0
Initialize the underlying engine that will process events, create windows, etc.
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
Definition Log.H:230
Main namespace for all JeVois classes and functions.
Definition Concepts.dox:2