Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
sk_app::Window_unix Class Reference

#include <Window_unix.h>

Inheritance diagram for sk_app::Window_unix:
sk_app::Window

Public Member Functions

 Window_unix ()
 
 ~Window_unix () override
 
bool initWindow (Display *display)
 
void setTitle (const char *) override
 
void show () override
 
const char * getClipboardText () override
 
void setClipboardText (const char *) override
 
bool attach (BackendType) override
 
void onInval () override
 
bool handleEvent (const XEvent &event)
 
void markPendingPaint ()
 
void finishPaint ()
 
void markPendingResize (int width, int height)
 
void finishResize ()
 
void setRequestedDisplayParams (const DisplayParams &, bool allowReattach) override
 
- Public Member Functions inherited from sk_app::Window
virtual ~Window ()
 
virtual void setUIState (const char *)
 
void inval ()
 
virtual bool scaleContentToFit () const
 
void detach ()
 
void pushLayer (Layer *layer)
 
void onBackendCreated ()
 
bool onChar (SkUnichar c, skui::ModifierKey modifiers)
 
bool onKey (skui::Key key, skui::InputState state, skui::ModifierKey modifiers)
 
bool onMouse (int x, int y, skui::InputState state, skui::ModifierKey modifiers)
 
bool onMouseWheel (float delta, int x, int y, skui::ModifierKey modifiers)
 
bool onTouch (intptr_t owner, skui::InputState state, float x, float y)
 
bool onFling (skui::InputState state)
 
bool onPinch (skui::InputState state, float scale, float x, float y)
 
void onUIStateChanged (const SkString &stateName, const SkString &stateValue)
 
void onPaint ()
 
void onResize (int width, int height)
 
void onActivate (bool isActive)
 
int width () const
 
int height () const
 
virtual float scaleFactor () const
 
virtual const DisplayParamsgetRequestedDisplayParams ()
 
int sampleCount () const
 
int stencilBits () const
 
GrDirectContextdirectContext () const
 
skgpu::graphite::ContextgraphiteContext () const
 
skgpu::graphite::RecordergraphiteRecorder () const
 

Static Public Member Functions

static const XWindowGetKey (const Window_unix &w)
 
static uint32_t Hash (const XWindow &w)
 
- Static Public Member Functions inherited from sk_app::Window
static WindowCreateNativeWindow (void *platformData)
 

Static Public Attributes

static SkTDynamicHash< Window_unix, XWindowgWindowMap
 

Additional Inherited Members

- Public Types inherited from sk_app::Window
enum  BackendType { kRaster_BackendType , kLast_BackendType = kRaster_BackendType }
 
enum  { kBackendTypeCount = kLast_BackendType + 1 }
 
- Protected Member Functions inherited from sk_app::Window
 Window ()
 
void markInvalProcessed ()
 
void visitLayers (const std::function< void(Layer *)> &visitor)
 
bool signalLayers (const std::function< bool(Layer *)> &visitor)
 
- Protected Attributes inherited from sk_app::Window
SkTDArray< Layer * > fLayers
 
DisplayParams fRequestedDisplayParams
 
bool fIsActive = true
 
std::unique_ptr< skwindow::WindowContextfWindowContext
 
bool fIsContentInvalidated = false
 

Detailed Description

Definition at line 24 of file Window_unix.h.

Constructor & Destructor Documentation

◆ Window_unix()

sk_app::Window_unix::Window_unix ( )
inline

Definition at line 26 of file Window_unix.h.

27 : Window()
28 , fDisplay(nullptr)
29 , fWindow(0)
30 , fGC(nullptr)
31 , fFBConfig(nullptr)
32 , fVisualInfo(nullptr)
33 , fMSAASampleCount(1) {}

◆ ~Window_unix()

sk_app::Window_unix::~Window_unix ( )
inlineoverride

Definition at line 34 of file Window_unix.h.

34{ this->closeWindow(); }

Member Function Documentation

◆ attach()

bool sk_app::Window_unix::attach ( BackendType  attachType)
overridevirtual

Implements sk_app::Window.

Definition at line 378 of file Window_unix.cpp.

378 {
379 fBackend = attachType;
380
381 this->initWindow(fDisplay);
382
384 winInfo.fDisplay = fDisplay;
385 winInfo.fWindow = fWindow;
386 winInfo.fFBConfig = fFBConfig;
387 winInfo.fVisualInfo = fVisualInfo;
388
389 XWindowAttributes attrs;
390 if (XGetWindowAttributes(fDisplay, fWindow, &attrs)) {
391 winInfo.fWidth = attrs.width;
392 winInfo.fHeight = attrs.height;
393 } else {
394 winInfo.fWidth = winInfo.fHeight = 0;
395 }
396
397 switch (attachType) {
398#if defined(SK_DAWN) && defined(SK_GRAPHITE)
399 case kGraphiteDawn_BackendType:
400 fWindowContext = skwindow::MakeGraphiteDawnVulkanForXlib(winInfo,
402 break;
403#endif
404#ifdef SK_VULKAN
405 case kVulkan_BackendType:
407 break;
408#endif
409#if defined(SK_VULKAN) && defined(SK_GRAPHITE)
410 case kGraphiteVulkan_BackendType:
412 break;
413#endif
414#ifdef SK_GL
415 case kNativeGL_BackendType:
416 fWindowContext = skwindow::MakeGLForXlib(winInfo, fRequestedDisplayParams);
417 break;
418#endif
421 break;
422 }
423 this->onBackendCreated();
424
425 return (SkToBool(fWindowContext));
426}
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
bool initWindow(Display *display)
@ kRaster_BackendType
Definition Window.h:90
DisplayParams fRequestedDisplayParams
Definition Window.h:171
std::unique_ptr< skwindow::WindowContext > fWindowContext
Definition Window.h:174
void onBackendCreated()
Definition Window.cpp:44
std::unique_ptr< WindowContext > MakeGraphiteVulkanForXlib(const XlibWindowInfo &info, const DisplayParams &displayParams)
std::unique_ptr< WindowContext > MakeRasterForXlib(const XlibWindowInfo &info, const DisplayParams &params)
std::unique_ptr< WindowContext > MakeVulkanForXlib(const XlibWindowInfo &info, const DisplayParams &displayParams)

◆ finishPaint()

void sk_app::Window_unix::finishPaint ( )
inline

Definition at line 61 of file Window_unix.h.

61 {
62 if (fPendingPaint) {
63 this->onPaint();
64 fPendingPaint = false;
65 }
66 }
void onPaint()
Definition Window.cpp:81

◆ finishResize()

void sk_app::Window_unix::finishResize ( )
inline

Definition at line 75 of file Window_unix.h.

75 {
76 if (fPendingResize) {
77 this->onResize(fPendingWidth, fPendingHeight);
78 fPendingResize = false;
79 }
80 }
void onResize(int width, int height)
Definition Window.cpp:108

◆ getClipboardText()

const char * sk_app::Window_unix::getClipboardText ( )
overridevirtual

Reimplemented from sk_app::Window.

Definition at line 460 of file Window_unix.cpp.

460 {
461 Atom UTF8 = XInternAtom(fDisplay, "UTF8_STRING", 0),
462 CLIPBOARD = XInternAtom(fDisplay, "CLIPBOARD", 0),
463 XSEL_DATA = XInternAtom(fDisplay, "XSEL_DATA", 0);
464
465 // Ask for a UTF8 copy of the CLIPBOARD...
466 XEvent event;
467 XConvertSelection(fDisplay, CLIPBOARD, UTF8, XSEL_DATA, fWindow, CurrentTime);
468 XSync(fDisplay, 0);
469 XNextEvent(fDisplay, &event);
470 if (event.type == SelectionNotify &&
471 event.xselection.selection == CLIPBOARD &&
472 event.xselection.property != None) {
473
474 // We got a response
475 Atom type;
476 int format;
477 unsigned long nitems, bytes_after;
478 char* data;
479
480 // Fetch the CLIPBOARD property
481 XSelectionEvent xsel = event.xselection;
482 XGetWindowProperty(xsel.display, xsel.requestor, xsel.property, /*offset=*/0,
483 /*length=*/~0L, /*delete=*/False, AnyPropertyType, &type, &format,
484 &nitems, &bytes_after, (unsigned char**)&data);
485 SkASSERT(bytes_after == 0);
486 if (type == UTF8) {
487 fClipboardText.assign(data, nitems);
488 }
489 XFree(data);
490 XDeleteProperty(xsel.display, xsel.requestor, xsel.property);
491 }
492 return fClipboardText.c_str();
493}
#define SkASSERT(cond)
Definition SkAssert.h:116
FlKeyEvent * event
uint32_t uint32_t * format
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41

◆ GetKey()

static const XWindow & sk_app::Window_unix::GetKey ( const Window_unix w)
inlinestatic

Definition at line 50 of file Window_unix.h.

50 {
51 return w.fWindow;
52 }
SkScalar w

◆ handleEvent()

bool sk_app::Window_unix::handleEvent ( const XEvent &  event)

Definition at line 249 of file Window_unix.cpp.

249 {
250 switch (event.type) {
251 case MapNotify:
252 if (!fGC) {
253 fGC = XCreateGC(fDisplay, fWindow, 0, nullptr);
254 }
255 break;
256
257 case ClientMessage:
258 if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage &&
259 gWindowMap.count() == 1) {
260 return true;
261 }
262 break;
263
264 case ButtonPress:
265 switch (event.xbutton.button) {
266 case Button1:
267 this->onMouse(event.xbutton.x, event.xbutton.y,
269 break;
270 case Button4:
271 this->onMouseWheel(1.0f, 0, 0, get_modifiers(event));
272 break;
273 case Button5:
274 this->onMouseWheel(-1.0f, 0, 0, get_modifiers(event));
275 break;
276 }
277 break;
278
279 case ButtonRelease:
280 if (event.xbutton.button == Button1) {
281 this->onMouse(event.xbutton.x, event.xbutton.y,
283 }
284 break;
285
286 case MotionNotify:
287 this->onMouse(event.xmotion.x, event.xmotion.y,
289 break;
290
291 case KeyPress: {
292 int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
293 KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode, 0, shiftLevel);
294 skui::Key key = get_key(keysym);
295 if (key != skui::Key::kNONE) {
297 if (keysym == XK_Escape) {
298 return true;
299 }
300 }
301 }
302
303 long uni = keysym2ucs(keysym);
304 if (uni != -1) {
305 (void) this->onChar((SkUnichar) uni, get_modifiers(event));
306 }
307 } break;
308
309 case KeyRelease: {
310 int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
311 KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
312 0, shiftLevel);
313 skui::Key key = get_key(keysym);
314 (void) this->onKey(key, skui::InputState::kUp,
316 } break;
317
318 case SelectionClear: {
319 // Lost selection ownership
320 fClipboardText.clear();
321 } break;
322
323 case SelectionRequest: {
324 Atom UTF8 = XInternAtom(fDisplay, "UTF8_STRING", 0),
325 CLIPBOARD = XInternAtom(fDisplay, "CLIPBOARD", 0);
326
327 const XSelectionRequestEvent* xsr = &event.xselectionrequest;
328
329 XSelectionEvent xsel = {};
330 xsel.type = SelectionNotify;
331 xsel.requestor = xsr->requestor;
332 xsel.selection = xsr->selection;
333 xsel.target = xsr->target;
334 xsel.property = xsr->property;
335 xsel.time = xsr->time;
336
337 if (xsr->selection != CLIPBOARD) {
338 // A request for a different kind of selection. This shouldn't happen.
339 break;
340 }
341
342 if (fClipboardText.empty() || xsr->target != UTF8 || xsr->property == None) {
343 // We can't fulfill this request. Deny it.
344 xsel.property = None;
345 XSendEvent(fDisplay, xsr->requestor, True, NoEventMask, (XEvent*)&xsel);
346 } else {
347 // We can fulfill this request! Update the contents of the CLIPBOARD property,
348 // and let the requestor know.
349 XChangeProperty(fDisplay, xsr->requestor, xsr->property, UTF8, /*format=*/8,
350 PropModeReplace, (unsigned char*)fClipboardText.data(),
351 fClipboardText.length());
352 XSendEvent(fDisplay, xsr->requestor, True, NoEventMask, (XEvent*)&xsel);
353 }
354 } break;
355
356 default:
357 // these events should be handled in the main event loop
358 SkASSERT(event.type != Expose && event.type != ConfigureNotify);
359 break;
360 }
361
362 return false;
363}
int32_t SkUnichar
Definition SkTypes.h:175
static SkTDynamicHash< Window_unix, XWindow > gWindowMap
Definition Window_unix.h:58
bool onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers)
Definition Window.cpp:52
bool onChar(SkUnichar c, skui::ModifierKey modifiers)
Definition Window.cpp:48
bool onMouseWheel(float delta, int x, int y, skui::ModifierKey modifiers)
Definition Window.cpp:60
bool onMouse(int x, int y, skui::InputState state, skui::ModifierKey modifiers)
Definition Window.cpp:56
long keysym2ucs(KeySym keysym)
Definition keysym2ucs.c:818
static skui::ModifierKey get_modifiers(const XEvent &event)
static skui::Key get_key(KeySym keysym)
Key
Definition Key.h:6
guint16 keycode

◆ Hash()

static uint32_t sk_app::Window_unix::Hash ( const XWindow w)
inlinestatic

Definition at line 54 of file Window_unix.h.

54 {
55 return SkChecksum::Mix(w);
56 }
static uint32_t Mix(uint32_t hash)
Definition SkChecksum.h:30

◆ initWindow()

bool sk_app::Window_unix::initWindow ( Display *  display)

Definition at line 44 of file Window_unix.cpp.

44 {
45 if (fRequestedDisplayParams.fMSAASampleCount != fMSAASampleCount) {
46 this->closeWindow();
47 }
48 // we already have a window
49 if (fDisplay) {
50 return true;
51 }
52 fDisplay = display;
53
54 constexpr int initialWidth = 1280;
55 constexpr int initialHeight = 960;
56
57#ifdef SK_GL
58 // Attempt to create a window that supports GL
59
60 // We prefer the more recent glXChooseFBConfig but fall back to glXChooseVisual. They have
61 // slight differences in how attributes are specified.
62 static int constexpr kChooseFBConfigAtt[] = {
63 GLX_RENDER_TYPE, GLX_RGBA_BIT,
64 GLX_DOUBLEBUFFER, True,
65 GLX_STENCIL_SIZE, 8,
66 None
67 };
68 // For some reason glXChooseVisual takes a non-const pointer to the attributes.
69 int chooseVisualAtt[] = {
70 GLX_RGBA,
71 GLX_DOUBLEBUFFER,
72 GLX_STENCIL_SIZE, 8,
73 None
74 };
75 SkASSERT(nullptr == fVisualInfo);
77 static const GLint kChooseFBConifgAttCnt = std::size(kChooseFBConfigAtt);
78 GLint msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 4];
79 memcpy(msaaChooseFBConfigAtt, kChooseFBConfigAtt, sizeof(kChooseFBConfigAtt));
80 SkASSERT(None == msaaChooseFBConfigAtt[kChooseFBConifgAttCnt - 1]);
81 msaaChooseFBConfigAtt[kChooseFBConifgAttCnt - 1] = GLX_SAMPLE_BUFFERS_ARB;
82 msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 0] = 1;
83 msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 1] = GLX_SAMPLES_ARB;
84 msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 2] = fRequestedDisplayParams.fMSAASampleCount;
85 msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 3] = None;
86 int n;
87 fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), msaaChooseFBConfigAtt, &n);
88 if (n > 0) {
89 fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
90 } else {
91 static const GLint kChooseVisualAttCnt = std::size(chooseVisualAtt);
92 GLint msaaChooseVisualAtt[kChooseVisualAttCnt + 4];
93 memcpy(msaaChooseVisualAtt, chooseVisualAtt, sizeof(chooseVisualAtt));
94 SkASSERT(None == msaaChooseVisualAtt[kChooseVisualAttCnt - 1]);
95 msaaChooseFBConfigAtt[kChooseVisualAttCnt - 1] = GLX_SAMPLE_BUFFERS_ARB;
96 msaaChooseFBConfigAtt[kChooseVisualAttCnt + 0] = 1;
97 msaaChooseFBConfigAtt[kChooseVisualAttCnt + 1] = GLX_SAMPLES_ARB;
98 msaaChooseFBConfigAtt[kChooseVisualAttCnt + 2] =
100 msaaChooseFBConfigAtt[kChooseVisualAttCnt + 3] = None;
101 fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaChooseVisualAtt);
102 fFBConfig = nullptr;
103 }
104 }
105 if (nullptr == fVisualInfo) {
106 int n;
107 fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), kChooseFBConfigAtt, &n);
108 if (n > 0) {
109 fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
110 } else {
111 fVisualInfo = glXChooseVisual(display, DefaultScreen(display), chooseVisualAtt);
112 fFBConfig = nullptr;
113 }
114 }
115
116 if (fVisualInfo) {
117 Colormap colorMap = XCreateColormap(display,
118 RootWindow(display, fVisualInfo->screen),
119 fVisualInfo->visual,
120 AllocNone);
121 XSetWindowAttributes swa;
122 swa.colormap = colorMap;
123 swa.event_mask = kEventMask;
124 fWindow = XCreateWindow(display,
125 RootWindow(display, fVisualInfo->screen),
126 0, 0, // x, y
127 initialWidth, initialHeight,
128 0, // border width
129 fVisualInfo->depth,
130 InputOutput,
131 fVisualInfo->visual,
132 CWEventMask | CWColormap,
133 &swa);
134 }
135#endif
136 if (!fWindow) {
137 // Create a simple window instead. We will not be able to show GL
138 fWindow = XCreateSimpleWindow(display,
139 DefaultRootWindow(display),
140 0, 0, // x, y
141 initialWidth, initialHeight,
142 0, // border width
143 0, // border value
144 0); // background value
145 XSelectInput(display, fWindow, kEventMask);
146 }
147
148 if (!fWindow) {
149 return false;
150 }
151
152 fMSAASampleCount = fRequestedDisplayParams.fMSAASampleCount;
153
154 // set up to catch window delete message
155 fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
156 XSetWMProtocols(display, fWindow, &fWmDeleteMessage, 1);
157
158 // add to hashtable of windows
159 gWindowMap.add(this);
160
161 // init event variables
162 fPendingPaint = false;
163 fPendingResize = false;
164
165 return true;
166}
const long kEventMask

◆ markPendingPaint()

void sk_app::Window_unix::markPendingPaint ( )
inline

Definition at line 60 of file Window_unix.h.

60{ fPendingPaint = true; }

◆ markPendingResize()

void sk_app::Window_unix::markPendingResize ( int  width,
int  height 
)
inline

Definition at line 68 of file Window_unix.h.

68 {
69 if (width != this->width() || height != this->height()){
70 fPendingResize = true;
71 fPendingWidth = width;
72 fPendingHeight = height;
73 }
74 }
int height() const
Definition Window.cpp:130
int width() const
Definition Window.cpp:123

◆ onInval()

void sk_app::Window_unix::onInval ( )
overridevirtual

Implements sk_app::Window.

Definition at line 428 of file Window_unix.cpp.

428 {
429 XEvent event;
430 event.type = Expose;
431 event.xexpose.send_event = True;
432 event.xexpose.display = fDisplay;
433 event.xexpose.window = fWindow;
434 event.xexpose.x = 0;
435 event.xexpose.y = 0;
436 event.xexpose.width = this->width();
437 event.xexpose.height = this->height();
438 event.xexpose.count = 0;
439
440 XSendEvent(fDisplay, fWindow, False, 0, &event);
441}

◆ setClipboardText()

void sk_app::Window_unix::setClipboardText ( const char *  text)
overridevirtual

Reimplemented from sk_app::Window.

Definition at line 495 of file Window_unix.cpp.

495 {
496 fClipboardText.assign(text);
497
498 // Take ownership of the CLIPBOARD
499 Atom CLIPBOARD = XInternAtom(fDisplay, "CLIPBOARD", 0);
500 XSetSelectionOwner(fDisplay, CLIPBOARD, fWindow, CurrentTime);
501}
std::u16string text

◆ setRequestedDisplayParams()

void sk_app::Window_unix::setRequestedDisplayParams ( const DisplayParams params,
bool  allowReattach 
)
overridevirtual

Reimplemented from sk_app::Window.

Definition at line 443 of file Window_unix.cpp.

443 {
444#if defined(SK_VULKAN)
445 // Vulkan on unix crashes if we try to reinitialize the vulkan context without remaking the
446 // window.
447 if (fBackend == kVulkan_BackendType && allowReattach) {
448 // Need to change these early, so attach() creates the window context correctly
450
451 this->detach();
452 this->attach(fBackend);
453 return;
454 }
455#endif
456
458}
bool attach(BackendType) override
void detach()
Definition Window.cpp:25
virtual void setRequestedDisplayParams(const DisplayParams &, bool allowReattach=true)
Definition Window.cpp:137
const EmbeddedViewParams * params

◆ setTitle()

void sk_app::Window_unix::setTitle ( const char *  title)
overridevirtual

Implements sk_app::Window.

Definition at line 365 of file Window_unix.cpp.

365 {
366 XTextProperty textproperty;
367 if (!XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty)) {
368 return;
369 }
370 XSetWMName(fDisplay, fWindow, &textproperty);
371 XFree(textproperty.value);
372}

◆ show()

void sk_app::Window_unix::show ( )
overridevirtual

Implements sk_app::Window.

Definition at line 374 of file Window_unix.cpp.

374 {
375 XMapWindow(fDisplay, fWindow);
376}

Member Data Documentation

◆ gWindowMap

SkTDynamicHash< Window_unix, XWindow > sk_app::Window_unix::gWindowMap
static

Definition at line 58 of file Window_unix.h.


The documentation for this class was generated from the following files: