rnd-20111007-1-src
[rocksndiamonds.git] / src / libgame / x11.c
index 88deb3f586d64092c772dc186e1a1cec4e0a2b38..66f4a3efc69b597beabb09091e23a01a57b02025 100644 (file)
@@ -1,7 +1,7 @@
 /***********************************************************
 * Artsoft Retro-Game Library                               *
 *----------------------------------------------------------*
-* (c) 1994-2002 Artsoft Entertainment                      *
+* (c) 1994-2006 Artsoft Entertainment                      *
 *               Holger Schemel                             *
 *               Detmolder Strasse 189                      *
 *               33604 Bielefeld                            *
 static void X11InitDisplay();
 static DrawWindow *X11InitWindow();
 
+static int X11DebugErrorHandler(Display *display, XErrorEvent *event)
+{
+  int x = 0;
+
+  return 1 / x;                /* !!! crash program to give backtrace in gdb !!! */
+}
+
 void X11InitVideoDisplay(void)
 {
   /* initialize X11 video */
@@ -33,13 +40,21 @@ void X11InitVideoDisplay(void)
 
 void X11InitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window)
 {
+  if (*window != NULL)
+    X11CloseWindow(*window);
+
   *window = X11InitWindow();
 
   XMapWindow(display, (*window)->drawable);
+
   FlushDisplay();
 
   /* create additional (off-screen) buffer for double-buffering */
+#if 1
+  ReCreateBitmap(backbuffer, video.width, video.height, video.depth);
+#else
   *backbuffer = CreateBitmap(video.width, video.height, video.depth);
+#endif
 }
 
 static void X11InitDisplay()
@@ -55,6 +70,14 @@ static void X11InitDisplay()
     Error(ERR_EXIT, "cannot connect to X server %s",
          XDisplayName(options.display_name));
 
+  if (options.debug_x11_sync)
+  {
+    Error(ERR_WARN, "running in X11 synchronous mode (debug only)");
+
+    XSynchronize(display, True);
+    XSetErrorHandler(X11DebugErrorHandler);
+  }
+
   screen = DefaultScreen(display);
   visual = DefaultVisual(display, screen);
   depth  = DefaultDepth(display, screen);
@@ -87,7 +110,7 @@ static DrawWindow *X11InitWindow()
   DrawWindow *new_window = CreateBitmapStruct();
   unsigned int border_width = 4;
   XGCValues gc_values;
-  unsigned long gc_valuemask;
+  unsigned int gc_valuemask;
 #if !defined(PLATFORM_MSDOS)
   XTextProperty windowName, iconName;
   Pixmap icon_pixmap, iconmask_pixmap;
@@ -98,13 +121,13 @@ static DrawWindow *X11InitWindow()
   XClassHint class_hints;
   char *window_name = program.window_title;
   char *icon_name = program.window_title;
-  long window_event_mask;
+  int window_event_mask;
   Atom proto_atom = None, delete_atom = None;
 #endif
   int screen_width, screen_height;
   int win_xpos, win_ypos;
-  unsigned long pen_fg = WhitePixel(display, screen);
-  unsigned long pen_bg = BlackPixel(display, screen);
+  unsigned int pen_fg = WhitePixel(display, screen);
+  unsigned int pen_bg = BlackPixel(display, screen);
   const int width = video.width, height = video.height;
   int i;
 
@@ -114,6 +137,9 @@ static DrawWindow *X11InitWindow()
   win_xpos = (screen_width - width) / 2;
   win_ypos = (screen_height - height) / 2;
 
+  new_window->width = width;
+  new_window->height = height;
+
   new_window->drawable = XCreateSimpleWindow(display,
                                             RootWindow(display, screen),
                                             win_xpos, win_ypos,
@@ -212,6 +238,20 @@ static DrawWindow *X11InitWindow()
   return new_window;
 }
 
+void X11CloseWindow(DrawWindow *window)
+{
+  if (window->drawable)
+  {
+    XUnmapWindow(display, window->drawable);
+    XDestroyWindow(display, window->drawable);
+  }
+
+  if (window->gc)
+    XFreeGC(display, window->gc);
+
+  free(window);
+}
+
 void X11ZoomBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap)
 {
 #if defined(TARGET_ALLEGRO)
@@ -249,7 +289,7 @@ Bitmap *X11LoadImage(char *filename)
   char *error = "Read_PCX_to_Pixmap(): %s '%s'";
   int pcx_err;
   XGCValues clip_gc_values;
-  unsigned long clip_gc_valuemask;
+  unsigned int clip_gc_valuemask;
 
   pcx_err = Read_PCX_to_Pixmap(display, window->drawable, window->gc, filename,
                               &new_bitmap->drawable, &new_bitmap->clip_mask);
@@ -363,14 +403,18 @@ void X11FillRectangle(Bitmap *bitmap, int x, int y,
 }
 
 void X11FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
-                     int fade_mode, int fade_delay, int post_delay)
+                     int fade_mode, int fade_delay, int post_delay,
+                     void (*draw_border_function)(void))
 {
   /* fading currently not supported -- simply copy backbuffer to screen */
 
   if (fade_mode == FADE_MODE_FADE_OUT)
-    X11FillRectangle(window, x, y, width, height, BLACK_PIXEL);
-  else
-    X11CopyArea(backbuffer, window, x, y, width, height, 0, 0, BLIT_OPAQUE);
+    X11FillRectangle(backbuffer, x, y, width, height, BLACK_PIXEL);
+
+  if (draw_border_function != NULL)
+    draw_border_function();
+
+  X11CopyArea(backbuffer, window, x, y, width, height, x, y, BLIT_OPAQUE);
 
   /* as we currently cannot use the fade delay, also do not use post delay */
 }