window.cpp 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include "window.hpp"
  2. using namespace slop;
  3. slop::SlopWindow::SlopWindow() {
  4. // Load up a opengl context
  5. static int attributeList[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT,
  6. GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
  7. GLX_DOUBLEBUFFER, True,
  8. GLX_RED_SIZE, 1,
  9. GLX_GREEN_SIZE, 1,
  10. GLX_BLUE_SIZE, 1,
  11. GLX_ALPHA_SIZE, 1,
  12. None };
  13. int nelements;
  14. int render_event_base, render_error_base;
  15. if(!XRenderQueryExtension(x11->display, &render_event_base, &render_error_base)) {
  16. throw std::runtime_error("No XRENDER extension found\n");
  17. }
  18. GLXFBConfig* fbc = glXChooseFBConfig(x11->display, DefaultScreen(x11->display), attributeList, &nelements);
  19. GLXFBConfig fbconfig;
  20. if ( !fbc ) {
  21. throw std::runtime_error("No matching visuals available.\n");
  22. }
  23. XVisualInfo* vi ;
  24. XRenderPictFormat *pictFormat;
  25. int i;
  26. for (i=0; i<nelements; i++) {
  27. vi = glXGetVisualFromFBConfig(x11->display, fbc[i]);
  28. if (!vi) { continue; }
  29. pictFormat = XRenderFindVisualFormat(x11->display, vi->visual);
  30. if (!pictFormat) {
  31. XFree( vi );
  32. continue;
  33. }
  34. if(pictFormat->direct.alphaMask > 0) {
  35. fbconfig = fbc[i];
  36. break;
  37. } else {
  38. XFree( vi );
  39. }
  40. }
  41. if (i == nelements ) {
  42. throw std::runtime_error( "No matching visuals available" );
  43. }
  44. XFree( fbc );
  45. XSetWindowAttributes attributes;
  46. attributes.colormap = XCreateColormap(x11->display, RootWindow(x11->display, vi->screen), vi->visual, AllocNone);
  47. attributes.background_pixmap = None;
  48. attributes.border_pixel = 0;
  49. // Disable window decorations.
  50. attributes.override_redirect = True;
  51. // Make sure we know when we've been successfully destroyed later!
  52. attributes.event_mask = StructureNotifyMask;
  53. unsigned long valueMask = CWOverrideRedirect | CWColormap | CWBackPixmap | CWBorderPixel | CWEventMask;
  54. // Create the window
  55. window = XCreateWindow( x11->display, x11->root, 0, 0, WidthOfScreen( x11->screen ), HeightOfScreen( x11->screen ),
  56. 0, vi->depth, InputOutput,
  57. vi->visual, valueMask, &attributes );
  58. XFree( vi );
  59. if ( !window ) {
  60. throw std::runtime_error( "Couldn't create a GL window!" );
  61. }
  62. // Prep some hints for the window
  63. static char title[] = "slop";
  64. XWMHints* startup_state = XAllocWMHints();
  65. startup_state->initial_state = NormalState;
  66. startup_state->flags = StateHint;
  67. XTextProperty textprop;
  68. textprop.value = (unsigned char*)title;
  69. textprop.encoding = XA_STRING;
  70. textprop.format = 8;
  71. textprop.nitems = strlen( title );
  72. XSizeHints sizehints;
  73. sizehints.x = 0;
  74. sizehints.y = 0;
  75. sizehints.width = WidthOfScreen( x11->screen );
  76. sizehints.height = HeightOfScreen( x11->screen );
  77. sizehints.flags = USPosition | USSize;
  78. XClassHint classhints;
  79. char name[] = "slop";
  80. classhints.res_name = name;
  81. classhints.res_class = name;
  82. // Finally send it all over...
  83. XSetClassHint( x11->display, window, &classhints );
  84. XSetWMProperties( x11->display, window, &textprop, &textprop, NULL, 0, &sizehints, startup_state, NULL );
  85. XFree( startup_state );
  86. // Keep the window on top of all other windows.
  87. Atom stateAbove = XInternAtom(x11->display, "_NET_WM_STATE_ABOVE", False);
  88. XChangeProperty(x11->display, window, XInternAtom(x11->display, "_NET_WM_STATE", False), XA_ATOM, 32, PropModeReplace, (unsigned char *) &stateAbove, 1);
  89. context = glXCreateNewContext( x11->display, fbconfig, GLX_RGBA_TYPE, 0, True );
  90. if ( !context ) {
  91. throw std::runtime_error( "Failed to create an OpenGL context." );
  92. }
  93. setCurrent();
  94. // Finally we grab some OpenGL 3.3 stuffs.
  95. GLenum err = glewInit();
  96. if (GLEW_OK != err)
  97. {
  98. throw std::runtime_error((char*)glewGetErrorString(err));
  99. }
  100. framebuffer = new Framebuffer( WidthOfScreen( x11->screen ), HeightOfScreen( x11->screen ) );
  101. glViewport( 0, 0, WidthOfScreen( x11->screen ), HeightOfScreen( x11->screen ) );
  102. camera = glm::ortho( 0.0f, (float)WidthOfScreen( x11->screen ), (float)HeightOfScreen( x11->screen ), 0.0f, -1.0f, 1.0f);
  103. // Last, we actually display the window <:o)
  104. XMapWindow( x11->display, window );
  105. }
  106. slop::SlopWindow::~SlopWindow() {
  107. delete framebuffer;
  108. // Try to erase the window before destroying it.
  109. glClearColor( 0, 0, 0, 0 );
  110. glClear( GL_COLOR_BUFFER_BIT );
  111. display();
  112. glClearColor( 0, 0, 0, 0 );
  113. glClear( GL_COLOR_BUFFER_BIT );
  114. display();
  115. glXDestroyContext( x11->display, context );
  116. XUnmapWindow( x11->display, window );
  117. XDestroyWindow( x11->display, window );
  118. glXMakeCurrent( x11->display, None, NULL );
  119. }
  120. void slop::SlopWindow::display() {
  121. glXSwapBuffers( x11->display, window );
  122. glXWaitGL();
  123. }
  124. void slop::SlopWindow::setCurrent() {
  125. glXMakeCurrent( x11->display, window, context );
  126. }