| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- // Copyright 2014 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- //go:build linux && !android
- // +build linux,!android
- #include "_cgo_export.h"
- #include <EGL/egl.h>
- #include <GLES2/gl2.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <stdio.h>
- #include <stdlib.h>
- static Atom wm_delete_window;
- static Window
- new_window(Display *x_dpy, EGLDisplay e_dpy, int w, int h, EGLContext *ctx, EGLSurface *surf) {
- static const EGLint attribs[] = {
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_BLUE_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_RED_SIZE, 8,
- EGL_DEPTH_SIZE, 16,
- EGL_CONFIG_CAVEAT, EGL_NONE,
- EGL_NONE
- };
- EGLConfig config;
- EGLint num_configs;
- if (!eglChooseConfig(e_dpy, attribs, &config, 1, &num_configs)) {
- fprintf(stderr, "eglChooseConfig failed\n");
- exit(1);
- }
- EGLint vid;
- if (!eglGetConfigAttrib(e_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
- fprintf(stderr, "eglGetConfigAttrib failed\n");
- exit(1);
- }
- XVisualInfo visTemplate;
- visTemplate.visualid = vid;
- int num_visuals;
- XVisualInfo *visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
- if (!visInfo) {
- fprintf(stderr, "XGetVisualInfo failed\n");
- exit(1);
- }
- Window root = RootWindow(x_dpy, DefaultScreen(x_dpy));
- XSetWindowAttributes attr;
- attr.colormap = XCreateColormap(x_dpy, root, visInfo->visual, AllocNone);
- if (!attr.colormap) {
- fprintf(stderr, "XCreateColormap failed\n");
- exit(1);
- }
- attr.event_mask = StructureNotifyMask | ExposureMask |
- ButtonPressMask | ButtonReleaseMask | ButtonMotionMask;
- Window win = XCreateWindow(
- x_dpy, root, 0, 0, w, h, 0, visInfo->depth, InputOutput,
- visInfo->visual, CWColormap | CWEventMask, &attr);
- XFree(visInfo);
- XSizeHints sizehints;
- sizehints.width = w;
- sizehints.height = h;
- sizehints.flags = USSize;
- XSetNormalHints(x_dpy, win, &sizehints);
- XSetStandardProperties(x_dpy, win, "App", "App", None, (char **)NULL, 0, &sizehints);
- static const EGLint ctx_attribs[] = {
- EGL_CONTEXT_CLIENT_VERSION, 2,
- EGL_NONE
- };
- *ctx = eglCreateContext(e_dpy, config, EGL_NO_CONTEXT, ctx_attribs);
- if (!*ctx) {
- fprintf(stderr, "eglCreateContext failed\n");
- exit(1);
- }
- *surf = eglCreateWindowSurface(e_dpy, config, win, NULL);
- if (!*surf) {
- fprintf(stderr, "eglCreateWindowSurface failed\n");
- exit(1);
- }
- return win;
- }
- Display *x_dpy;
- EGLDisplay e_dpy;
- EGLContext e_ctx;
- EGLSurface e_surf;
- Window win;
- void
- createWindow(void) {
- x_dpy = XOpenDisplay(NULL);
- if (!x_dpy) {
- fprintf(stderr, "XOpenDisplay failed\n");
- exit(1);
- }
- e_dpy = eglGetDisplay(x_dpy);
- if (!e_dpy) {
- fprintf(stderr, "eglGetDisplay failed\n");
- exit(1);
- }
- EGLint e_major, e_minor;
- if (!eglInitialize(e_dpy, &e_major, &e_minor)) {
- fprintf(stderr, "eglInitialize failed\n");
- exit(1);
- }
- eglBindAPI(EGL_OPENGL_ES_API);
- win = new_window(x_dpy, e_dpy, 600, 800, &e_ctx, &e_surf);
- wm_delete_window = XInternAtom(x_dpy, "WM_DELETE_WINDOW", True);
- if (wm_delete_window != None) {
- XSetWMProtocols(x_dpy, win, &wm_delete_window, 1);
- }
- XMapWindow(x_dpy, win);
- if (!eglMakeCurrent(e_dpy, e_surf, e_surf, e_ctx)) {
- fprintf(stderr, "eglMakeCurrent failed\n");
- exit(1);
- }
- // Window size and DPI should be initialized before starting app.
- XEvent ev;
- while (1) {
- if (XCheckMaskEvent(x_dpy, StructureNotifyMask, &ev) == False) {
- continue;
- }
- if (ev.type == ConfigureNotify) {
- onResize(ev.xconfigure.width, ev.xconfigure.height);
- break;
- }
- }
- }
- void
- processEvents(void) {
- while (XPending(x_dpy)) {
- XEvent ev;
- XNextEvent(x_dpy, &ev);
- switch (ev.type) {
- case ButtonPress:
- onTouchBegin((float)ev.xbutton.x, (float)ev.xbutton.y);
- break;
- case ButtonRelease:
- onTouchEnd((float)ev.xbutton.x, (float)ev.xbutton.y);
- break;
- case MotionNotify:
- onTouchMove((float)ev.xmotion.x, (float)ev.xmotion.y);
- break;
- case ConfigureNotify:
- onResize(ev.xconfigure.width, ev.xconfigure.height);
- break;
- case ClientMessage:
- if (wm_delete_window != None && (Atom)ev.xclient.data.l[0] == wm_delete_window) {
- onStop();
- return;
- }
- break;
- }
- }
- }
- void
- swapBuffers(void) {
- if (eglSwapBuffers(e_dpy, e_surf) == EGL_FALSE) {
- fprintf(stderr, "eglSwapBuffer failed\n");
- exit(1);
- }
- }
|