54 constexpr int initialWidth = 1280;
55 constexpr int initialHeight = 960;
62 static int constexpr kChooseFBConfigAtt[] = {
63 GLX_RENDER_TYPE, GLX_RGBA_BIT,
64 GLX_DOUBLEBUFFER, True,
69 int chooseVisualAtt[] = {
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;
85 msaaChooseFBConfigAtt[kChooseFBConifgAttCnt + 3] = None;
87 fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), msaaChooseFBConfigAtt, &n);
89 fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
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);
105 if (
nullptr == fVisualInfo) {
107 fFBConfig = glXChooseFBConfig(fDisplay, DefaultScreen(fDisplay), kChooseFBConfigAtt, &n);
109 fVisualInfo = glXGetVisualFromFBConfig(fDisplay, *fFBConfig);
111 fVisualInfo = glXChooseVisual(display, DefaultScreen(display), chooseVisualAtt);
117 Colormap colorMap = XCreateColormap(display,
118 RootWindow(display, fVisualInfo->screen),
121 XSetWindowAttributes swa;
122 swa.colormap = colorMap;
124 fWindow = XCreateWindow(display,
125 RootWindow(display, fVisualInfo->screen),
127 initialWidth, initialHeight,
132 CWEventMask | CWColormap,
138 fWindow = XCreateSimpleWindow(display,
139 DefaultRootWindow(display),
141 initialWidth, initialHeight,
155 fWmDeleteMessage = XInternAtom(display,
"WM_DELETE_WINDOW", False);
156 XSetWMProtocols(display, fWindow, &fWmDeleteMessage, 1);
162 fPendingPaint =
false;
163 fPendingResize =
false;
191 static const struct {
195 { XK_BackSpace, skui::Key::kBack },
196 { XK_Clear, skui::Key::kBack },
197 { XK_Return, skui::Key::kOK },
198 { XK_Up, skui::Key::kUp },
199 { XK_Down, skui::Key::kDown },
200 { XK_Left, skui::Key::kLeft },
201 { XK_Right, skui::Key::kRight },
202 { XK_Tab, skui::Key::kTab },
203 { XK_Page_Up, skui::Key::kPageUp },
204 { XK_Page_Down, skui::Key::kPageDown },
205 { XK_Home, skui::Key::kHome },
206 { XK_End, skui::Key::kEnd },
207 { XK_Delete, skui::Key::kDelete },
208 { XK_Escape, skui::Key::kEscape },
209 { XK_Shift_L, skui::Key::kShift },
210 { XK_Shift_R, skui::Key::kShift },
211 { XK_Control_L, skui::Key::kCtrl },
212 { XK_Control_R, skui::Key::kCtrl },
213 { XK_Alt_L, skui::Key::kOption },
214 { XK_Alt_R, skui::Key::kOption },
215 {
'a', skui::Key::kA },
216 {
'c', skui::Key::kC },
217 {
'v', skui::Key::kV },
218 {
'x', skui::Key::kX },
219 {
'y', skui::Key::kY },
220 {
'z', skui::Key::kZ },
222 for (
size_t i = 0; i < std::size(gPair); i++) {
223 if (gPair[i].fXK == keysym) {
224 return gPair[i].fKey;
227 return skui::Key::kNONE;
250 switch (
event.type) {
253 fGC = XCreateGC(fDisplay, fWindow, 0,
nullptr);
258 if ((Atom)
event.xclient.data.l[0] == fWmDeleteMessage &&
265 switch (
event.xbutton.button) {
280 if (
event.xbutton.button == Button1) {
292 int shiftLevel = (
event.xkey.state & ShiftMask) ? 1 : 0;
293 KeySym keysym = XkbKeycodeToKeysym(fDisplay,
event.xkey.
keycode, 0, shiftLevel);
295 if (
key != skui::Key::kNONE) {
297 if (keysym == XK_Escape) {
310 int shiftLevel = (
event.xkey.state & ShiftMask) ? 1 : 0;
311 KeySym keysym = XkbKeycodeToKeysym(fDisplay,
event.xkey.
keycode,
318 case SelectionClear: {
320 fClipboardText.clear();
323 case SelectionRequest: {
324 Atom UTF8 = XInternAtom(fDisplay,
"UTF8_STRING", 0),
325 CLIPBOARD = XInternAtom(fDisplay,
"CLIPBOARD", 0);
327 const XSelectionRequestEvent* xsr = &
event.xselectionrequest;
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;
337 if (xsr->selection != CLIPBOARD) {
342 if (fClipboardText.empty() || xsr->target != UTF8 || xsr->property == None) {
344 xsel.property = None;
345 XSendEvent(fDisplay, xsr->requestor, True, NoEventMask, (XEvent*)&xsel);
349 XChangeProperty(fDisplay, xsr->requestor, xsr->property, UTF8, 8,
350 PropModeReplace, (
unsigned char*)fClipboardText.data(),
351 fClipboardText.length());
352 XSendEvent(fDisplay, xsr->requestor, True, NoEventMask, (XEvent*)&xsel);
461 Atom UTF8 = XInternAtom(fDisplay,
"UTF8_STRING", 0),
462 CLIPBOARD = XInternAtom(fDisplay,
"CLIPBOARD", 0),
463 XSEL_DATA = XInternAtom(fDisplay,
"XSEL_DATA", 0);
467 XConvertSelection(fDisplay, CLIPBOARD, UTF8, XSEL_DATA, fWindow, CurrentTime);
469 XNextEvent(fDisplay, &
event);
470 if (
event.type == SelectionNotify &&
471 event.xselection.selection == CLIPBOARD &&
472 event.xselection.property != None) {
477 unsigned long nitems, bytes_after;
481 XSelectionEvent xsel =
event.xselection;
482 XGetWindowProperty(xsel.display, xsel.requestor, xsel.property, 0,
484 &nitems, &bytes_after, (
unsigned char**)&data);
487 fClipboardText.assign(data, nitems);
490 XDeleteProperty(xsel.display, xsel.requestor, xsel.property);
492 return fClipboardText.c_str();
uint32_t uint32_t * format