// Example C program that ensures the graphic shell works. // This tests the native layer implmentation without golang. int main( void ) { // initialize the window. gs_set_attr_s(GS_AppName, "Test Window"); long long display = gs_display_init(); if (display == 0) { printf("Failed display init.\n"); exit( EXIT_FAILURE ); } // create the window. long long shell = gs_shell(display); printf("display %ld shell %ld\n", (long)display, (long)shell); long long context = gs_context(&display, &shell); printf("display %ld shell %ld context %ld\n", (long)display, (long)shell, (long)context); if (context == 0) { printf("Failed context init.\n"); exit( EXIT_FAILURE ); } gs_shell_open(display); long x, y, w, h; gs_size(display, &x, &y, &w, &h); printf("shell size %ld::%ld ", w, h); // process user events. GSEvent gsu = {-1, 0, 0, 0, 0, 0}; while (gs_shell_alive(display)) { gsu.event = -1; gsu.mousex = 0; gsu.mousey = 0; gsu.key = 0; gsu.mods = 0; gsu.scroll = 0; gs_read_dispatch(display, &gsu); if (gsu.event >= 0) { // show current key code printf("mouse %ld,%ld - ", gsu.mousex, gsu.mousey); printf("[mods 0x%.2lX] - ", gsu.mods); if (gsu.event == GS_KeyUp) { printf("key up 0x%.2lX - ", gsu.key); } else if (gsu.event == GS_KeyDown) { printf("key down 0x%.2lX - ", gsu.key); // test copy and paste. if (gsu.key == 0x43) { // c key char *s = gs_clip_copy(display); printf(" \"%s\"", s); free(s); } else if (gsu.key == 0x50) { // p key gs_clip_paste(display, "test paste string"); } } else if (gsu.event == GS_ScrollWheel) { printf("wheel %ld - ", gsu.scroll); } else { printf("event %ld - ", gsu.event); } printf("\n"); } gs_swap_buffers(shell); } gs_display_dispose(display); return 0; };
// gs_context creates an opengl context. Actually it creates two of them. // The first context is used to find better functions to create the final // context. Note that the pixel format is done only once for a window so // it must be correctly chosen. long gs_context(long long * display, long long * shell) { // create the initial context. HDC hdc = LongToHandle(*shell); HGLRC initialContext; int initial_pixelFormat = gs_get_initial_pixelformat(*shell); if (initial_pixelFormat != 0) { initialContext = wglCreateContext(hdc); if (initialContext != NULL) { if (!wglMakeCurrent(hdc, initialContext)) { wglDeleteContext(initialContext); initialContext = NULL; } } } if (initialContext == NULL) { return 0; // failed to get even a simple context. } // now that there is a context, bind the opengl extensions and fail // if the supported extensions are too old or if they are not there. gs_wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) wglGetProcAddress( "wglGetExtensionsStringEXT" ); gs_wglSwapIntervalARB = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress( "wglSwapIntervalEXT" ); gs_wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) wglGetProcAddress( "wglGetExtensionsStringARB" ); gs_wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress( "wglCreateContextAttribsARB" ); gs_wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) wglGetProcAddress( "wglGetPixelFormatAttribivARB" ); gs_wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress( "wglChoosePixelFormatARB" ); if (gs_wglGetExtensionsStringEXT == NULL || gs_wglSwapIntervalARB == NULL || gs_wglGetExtensionsStringARB == NULL || gs_wglCreateContextAttribsARB == NULL || gs_wglGetPixelFormatAttribivARB == NULL || gs_wglChoosePixelFormatARB == NULL) { return 0; } // destroy and recreate the window and shell LPSTR gs_className = TEXT("GS_WIN"); gs_display_dispose(*display); HMODULE hInstance = GetModuleHandle(NULL); *display = gs_create_window(hInstance, gs_className); *shell = gs_shell(*display); int pixelformat = gs_get_pixelformat(*shell); if (pixelformat == 0) { return 0; } // now create the context on the fresh window. int cnt = 0; int attribs[40]; hdc = LongToHandle(*shell); // Use the expected baseline opengl 3.2 attribs[cnt++] = WGL_CONTEXT_MAJOR_VERSION_ARB; attribs[cnt++] = 3; attribs[cnt++] = WGL_CONTEXT_MINOR_VERSION_ARB; attribs[cnt++] = 2; attribs[cnt++] = WGL_CONTEXT_FLAGS_ARB; attribs[cnt++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; attribs[cnt++] = WGL_CONTEXT_PROFILE_MASK_ARB; attribs[cnt++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; attribs[cnt++] = 0; HGLRC context = gs_wglCreateContextAttribsARB( hdc, NULL, attribs ); if (context != NULL) { if (wglMakeCurrent(hdc, context)) { return HandleToLong(context); } } return 0; // failed to get rendering context }