github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/exp/shiny/driver/gldriver/x11.c (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build linux,!android
     6  
     7  #include "_cgo_export.h"
     8  #include <EGL/egl.h>
     9  #include <stdio.h>
    10  #include <stdlib.h>
    11  
    12  EGLConfig e_config;
    13  EGLContext e_ctx;
    14  EGLDisplay e_dpy;
    15  Colormap x_colormap;
    16  Display *x_dpy;
    17  XVisualInfo *x_visual_info;
    18  Window x_root;
    19  
    20  char *
    21  eglGetErrorStr() {
    22  	switch (eglGetError()) {
    23  	case EGL_SUCCESS:
    24  		return "EGL_SUCCESS";
    25  	case EGL_NOT_INITIALIZED:
    26  		return "EGL_NOT_INITIALIZED";
    27  	case EGL_BAD_ACCESS:
    28  		return "EGL_BAD_ACCESS";
    29  	case EGL_BAD_ALLOC:
    30  		return "EGL_BAD_ALLOC";
    31  	case EGL_BAD_ATTRIBUTE:
    32  		return "EGL_BAD_ATTRIBUTE";
    33  	case EGL_BAD_CONFIG:
    34  		return "EGL_BAD_CONFIG";
    35  	case EGL_BAD_CONTEXT:
    36  		return "EGL_BAD_CONTEXT";
    37  	case EGL_BAD_CURRENT_SURFACE:
    38  		return "EGL_BAD_CURRENT_SURFACE";
    39  	case EGL_BAD_DISPLAY:
    40  		return "EGL_BAD_DISPLAY";
    41  	case EGL_BAD_MATCH:
    42  		return "EGL_BAD_MATCH";
    43  	case EGL_BAD_NATIVE_PIXMAP:
    44  		return "EGL_BAD_NATIVE_PIXMAP";
    45  	case EGL_BAD_NATIVE_WINDOW:
    46  		return "EGL_BAD_NATIVE_WINDOW";
    47  	case EGL_BAD_PARAMETER:
    48  		return "EGL_BAD_PARAMETER";
    49  	case EGL_BAD_SURFACE:
    50  		return "EGL_BAD_SURFACE";
    51  	case EGL_CONTEXT_LOST:
    52  		return "EGL_CONTEXT_LOST";
    53  	}
    54  	return "unknown EGL error";
    55  }
    56  
    57  void
    58  startDriver() {
    59  	x_dpy = XOpenDisplay(NULL);
    60  	if (!x_dpy) {
    61  		fprintf(stderr, "XOpenDisplay failed\n");
    62  		exit(1);
    63  	}
    64  	e_dpy = eglGetDisplay(x_dpy);
    65  	if (!e_dpy) {
    66  		fprintf(stderr, "eglGetDisplay failed: %s\n", eglGetErrorStr());
    67  		exit(1);
    68  	}
    69  	EGLint e_major, e_minor;
    70  	if (!eglInitialize(e_dpy, &e_major, &e_minor)) {
    71  		fprintf(stderr, "eglInitialize failed: %s\n", eglGetErrorStr());
    72  		exit(1);
    73  	}
    74  	if (!eglBindAPI(EGL_OPENGL_ES_API)) {
    75  		fprintf(stderr, "eglBindAPI failed: %s\n", eglGetErrorStr());
    76  		exit(1);
    77  	}
    78  
    79  	static const EGLint attribs[] = {
    80  		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    81  		EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    82  		EGL_BLUE_SIZE, 8,
    83  		EGL_GREEN_SIZE, 8,
    84  		EGL_RED_SIZE, 8,
    85  		EGL_DEPTH_SIZE, 16,
    86  		EGL_CONFIG_CAVEAT, EGL_NONE,
    87  		EGL_NONE
    88  	};
    89  	EGLint num_configs;
    90  	if (!eglChooseConfig(e_dpy, attribs, &e_config, 1, &num_configs)) {
    91  		fprintf(stderr, "eglChooseConfig failed: %s\n", eglGetErrorStr());
    92  		exit(1);
    93  	}
    94  	EGLint vid;
    95  	if (!eglGetConfigAttrib(e_dpy, e_config, EGL_NATIVE_VISUAL_ID, &vid)) {
    96  		fprintf(stderr, "eglGetConfigAttrib failed: %s\n", eglGetErrorStr());
    97  		exit(1);
    98  	}
    99  
   100  	XVisualInfo visTemplate;
   101  	visTemplate.visualid = vid;
   102  	int num_visuals;
   103  	x_visual_info = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
   104  	if (!x_visual_info) {
   105  		fprintf(stderr, "XGetVisualInfo failed\n");
   106  		exit(1);
   107  	}
   108  
   109  	x_root = RootWindow(x_dpy, DefaultScreen(x_dpy));
   110  	x_colormap = XCreateColormap(x_dpy, x_root, x_visual_info->visual, AllocNone);
   111  	if (!x_colormap) {
   112  		fprintf(stderr, "XCreateColormap failed\n");
   113  		exit(1);
   114  	}
   115  
   116  	static const EGLint ctx_attribs[] = {
   117  		EGL_CONTEXT_CLIENT_VERSION, 2,
   118  		EGL_NONE
   119  	};
   120  	e_ctx = eglCreateContext(e_dpy, e_config, EGL_NO_CONTEXT, ctx_attribs);
   121  	if (!e_ctx) {
   122  		fprintf(stderr, "eglCreateContext failed: %s\n", eglGetErrorStr());
   123  		exit(1);
   124  	}
   125  }
   126  
   127  void
   128  processEvents() {
   129  	while (XPending(x_dpy)) {
   130  		XEvent ev;
   131  		XNextEvent(x_dpy, &ev);
   132  		switch (ev.type) {
   133  		case ButtonPress:
   134  		case ButtonRelease:
   135  			onMouse(ev.xbutton.window, ev.xbutton.x, ev.xbutton.y, ev.xbutton.state, ev.xbutton.button,
   136  				ev.type == ButtonPress ? 1 : 2);
   137  			break;
   138  		case MotionNotify:
   139  			onMouse(ev.xmotion.window, ev.xmotion.x, ev.xmotion.y, ev.xmotion.state, 0, 0);
   140  			break;
   141  		case Expose:
   142  			// A non-zero Count means that there are more expose events coming. For
   143  			// example, a non-rectangular exposure (e.g. from a partially overlapped
   144  			// window) will result in multiple expose events whose dirty rectangles
   145  			// combine to define the dirty region. Go's paint events do not provide
   146  			// dirty regions, so we only pass on the final X11 expose event.
   147  			if (ev.xexpose.count == 0) {
   148  				onExpose(ev.xexpose.window);
   149  			}
   150  			break;
   151  		case ConfigureNotify:
   152  			onResize(ev.xconfigure.window, ev.xconfigure.width, ev.xconfigure.height);
   153  			break;
   154  		}
   155  	}
   156  }
   157  
   158  void
   159  makeCurrent(uintptr_t surface) {
   160  	EGLSurface surf = (EGLSurface)(surface);
   161  	if (!eglMakeCurrent(e_dpy, surf, surf, e_ctx)) {
   162  		fprintf(stderr, "eglMakeCurrent failed: %s\n", eglGetErrorStr());
   163  		exit(1);
   164  	}
   165  }
   166  
   167  void
   168  swapBuffers(uintptr_t surface) {
   169  	EGLSurface surf = (EGLSurface)(surface);
   170  	if (!eglSwapBuffers(e_dpy, surf)) {
   171  		fprintf(stderr, "eglSwapBuffers failed: %s\n", eglGetErrorStr());
   172  		exit(1);
   173  	}
   174  }
   175  
   176  uintptr_t
   177  doNewWindow(int width, int height) {
   178  	XSetWindowAttributes attr;
   179  	attr.colormap = x_colormap;
   180  	attr.event_mask =
   181  		ButtonPressMask |
   182  		ButtonReleaseMask |
   183  		PointerMotionMask |
   184  		ButtonMotionMask |
   185  		ExposureMask |
   186  		StructureNotifyMask;
   187  	Window win = XCreateWindow(
   188  		x_dpy, x_root, 0, 0, width, height, 0, x_visual_info->depth, InputOutput,
   189  		x_visual_info->visual, CWColormap | CWEventMask, &attr);
   190  	XSizeHints sizehints;
   191  	sizehints.width = width;
   192  	sizehints.height = height;
   193  	sizehints.flags = USSize;
   194  	XSetNormalHints(x_dpy, win, &sizehints);
   195  	XSetStandardProperties(x_dpy, win, "App", "App", None, (char **)NULL, 0, &sizehints);
   196  	return win;
   197  }
   198  
   199  uintptr_t
   200  doShowWindow(uintptr_t id) {
   201  	Window win = (Window)(id);
   202  	XMapWindow(x_dpy, win);
   203  	EGLSurface surf = eglCreateWindowSurface(e_dpy, e_config, win, NULL);
   204  	if (!surf) {
   205  		fprintf(stderr, "eglCreateWindowSurface failed: %s\n", eglGetErrorStr());
   206  		exit(1);
   207  	}
   208  	return (uintptr_t)(surf);
   209  }