sdl.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include <sys/ipc.h>
  2. #include <sys/shm.h>
  3. #include <X11/Xlib.h>
  4. #include <X11/Xutil.h>
  5. #include <X11/Xatom.h>
  6. #include <X11/extensions/Xv.h>
  7. #include <X11/extensions/Xvlib.h>
  8. #include <X11/extensions/XShm.h>
  9. #include <SDL/SDL.h>
  10. namespace ruby {
  11. #include "sdl.hpp"
  12. class pVideoSDL {
  13. public:
  14. VideoSDL &self;
  15. Display *display;
  16. SDL_Surface *screen, *buffer;
  17. struct {
  18. uintptr_t handle;
  19. } settings;
  20. bool cap(Video::Setting setting) {
  21. if(setting == Video::Handle) return true;
  22. return false;
  23. }
  24. uintptr_t get(Video::Setting setting) {
  25. if(setting == Video::Handle) return settings.handle;
  26. return false;
  27. }
  28. bool set(Video::Setting setting, uintptr_t param) {
  29. if(setting == Video::Handle) {
  30. settings.handle = param;
  31. return true;
  32. }
  33. return false;
  34. }
  35. bool lock(uint32_t *&data, unsigned &pitch) {
  36. if(SDL_MUSTLOCK(buffer)) SDL_LockSurface(buffer);
  37. pitch = buffer->pitch;
  38. return data = (uint32_t*)buffer->pixels;
  39. }
  40. void unlock() {
  41. if(SDL_MUSTLOCK(buffer)) SDL_UnlockSurface(buffer);
  42. }
  43. void clear() {
  44. if(SDL_MUSTLOCK(buffer)) SDL_LockSurface(buffer);
  45. uint32_t *data = (uint32_t*)buffer->pixels;
  46. for(unsigned y = 0; y < 1024; y++) {
  47. for(unsigned x = 0; x < 1024; x++) {
  48. *data++ |= 0xff000000;
  49. }
  50. data += (buffer->pitch >> 2) - 1024;
  51. }
  52. if(SDL_MUSTLOCK(buffer)) SDL_UnlockSurface(buffer);
  53. refresh(1024, 1024);
  54. }
  55. void refresh(unsigned width, unsigned height) {
  56. //ruby input is X8R8G8B8, top 8-bits are ignored.
  57. //as SDL forces us to use a 32-bit buffer, we must set alpha to 255 (full opacity)
  58. //to prevent blending against the window beneath when X window visual is 32-bits.
  59. if(SDL_MUSTLOCK(buffer)) SDL_LockSurface(buffer);
  60. uint32_t *data = (uint32_t*)buffer->pixels;
  61. for(unsigned y = 0; y < height; y++) {
  62. for(unsigned x = 0; x < width; x++) {
  63. *data++ |= 0xff000000;
  64. }
  65. data += (buffer->pitch >> 2) - width;
  66. }
  67. if(SDL_MUSTLOCK(buffer)) SDL_UnlockSurface(buffer);
  68. XWindowAttributes attributes;
  69. XGetWindowAttributes(display, settings.handle, &attributes);
  70. SDL_Rect src, dest;
  71. src.x = 0;
  72. src.y = 0;
  73. src.w = width;
  74. src.h = height;
  75. dest.x = 0;
  76. dest.y = 0;
  77. dest.w = attributes.width;
  78. dest.h = attributes.height;
  79. SDL_SoftStretch(buffer, &src, screen, &dest);
  80. SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
  81. }
  82. bool init() {
  83. //display = XOpenDisplay(0);
  84. char env[512];
  85. sprintf(env, "SDL_WINDOWID=%ld", settings.handle);
  86. putenv(env);
  87. printf("init sdl\n");
  88. SDL_InitSubSystem(SDL_INIT_VIDEO);
  89. //screen depth must be 32, as 24bpp with a 32-bit X window visual produces no output.
  90. printf("init screen\n");
  91. screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE);
  92. //makescreen = SDL_SetVideoMode(2560, 1600, 32, SDL_HWSURFACE);
  93. //buffer depth must be 32, as this is the input format used by all ruby drivers.
  94. printf("init surface\n");
  95. buffer = SDL_CreateRGBSurface(SDL_HWSURFACE,
  96. 1024, 1024, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
  97. );
  98. printf("init done\n");
  99. return true;
  100. }
  101. void term() {
  102. SDL_QuitSubSystem(SDL_INIT_VIDEO);
  103. }
  104. pVideoSDL(VideoSDL &self_) : self(self_) {
  105. settings.handle = 0;
  106. }
  107. };
  108. bool VideoSDL::cap(Setting setting) { return p.cap(setting); }
  109. uintptr_t VideoSDL::get(Setting setting) { return p.get(setting); }
  110. bool VideoSDL::set(Setting setting, uintptr_t param) { return p.set(setting, param); }
  111. bool VideoSDL::lock(uint32_t *&data, unsigned &pitch) { return p.lock(data, pitch); }
  112. void VideoSDL::unlock() { p.unlock(); }
  113. void VideoSDL::clear() { p.clear(); }
  114. void VideoSDL::refresh(unsigned width, unsigned height) { p.refresh(width, height); }
  115. bool VideoSDL::init() { return p.init(); }
  116. void VideoSDL::term() { p.term(); }
  117. VideoSDL::VideoSDL() : p(*new pVideoSDL(*this)) {}
  118. VideoSDL::~VideoSDL() { delete &p; }
  119. } //namespace ruby