ekiga r6952 - in trunk: . lib/gui src/gui



Author: mschneid
Date: Sat Sep 13 08:24:49 2008
New Revision: 6952
URL: http://svn.gnome.org/viewvc/ekiga?rev=6952&view=rev

Log:
Fix a rare crash when using SHM over a remote X connection.
X explicitly tells us we can use SHM (which IS supported
by the X server) but does not tell us attach will crash since
client and server do not even have shared memory since they are
different systems. Thus me must catch the X error on XShmAttach
to see if we can use it or not.


Modified:
   trunk/ChangeLog
   trunk/lib/gui/xvwindow.cpp
   trunk/lib/gui/xwindow.cpp
   trunk/lib/gui/xwindow.h
   trunk/src/gui/main.cpp

Modified: trunk/lib/gui/xvwindow.cpp
==============================================================================
--- trunk/lib/gui/xvwindow.cpp	(original)
+++ trunk/lib/gui/xvwindow.cpp	Sat Sep 13 08:24:49 2008
@@ -40,14 +40,18 @@
 
 #include <ptlib/object.h>
 
+#define GUID_I420_PLANAR 0x30323449
+#define GUID_YV12_PLANAR 0x32315659
+
 #ifdef HAVE_SHM
 #include <sys/shm.h>
 #include <sys/ipc.h>
-#endif
-
-#define GUID_I420_PLANAR 0x30323449
-#define GUID_YV12_PLANAR 0x32315659
 
+static void catchXShmError(Display * , XErrorEvent * )
+{
+  XWindow::_shmError = true;
+}
+#endif
 
 XVWindow::XVWindow()
 {
@@ -703,18 +707,26 @@
       _XShmInfo[i].readOnly = False;
   
       // Attaching the shared memory to the display
-      if (!XShmAttach (_display, &_XShmInfo[i])) {
+      XErrorHandler oldHandler = XSetErrorHandler((XErrorHandler) catchXShmError);
+      Status status = XShmAttach (_display, &_XShmInfo[i]);
+      XSync(_display, False);
+      XSetErrorHandler((XErrorHandler) oldHandler);
+
+      if ( (status != True) || (_shmError) ) {
         XFree (_XVImage[i]);
         _XVImage[i] = NULL;
-        if (_XShmInfo[i].shmaddr != ((char *) -1))
+        if (_XShmInfo[i].shmaddr != ((char *) -1)) {
           shmdt(_XShmInfo[i].shmaddr);
+        }
         PTRACE(1, "XVideo\t  XShmAttach failed");
+        if ( (status == True) && (_shmError) ) {
+          PTRACE(1, "XVideo\t  X server supports SHM but apparently we are remotely connected...");
+        }
         _useShm = false;
       } 
     } 
   
     if (_useShm) {
-      XSync(_display, False);
       shmctl(_XShmInfo[i].shmid, IPC_RMID, 0);
     }
   }

Modified: trunk/lib/gui/xwindow.cpp
==============================================================================
--- trunk/lib/gui/xwindow.cpp	(original)
+++ trunk/lib/gui/xwindow.cpp	Sat Sep 13 08:24:49 2008
@@ -85,6 +85,15 @@
   {NULL, 0, 0, 0, 0, 0, 0}
 };
 
+#ifdef HAVE_SHM
+bool XWindow::_shmError = false;
+
+static void catchXShmError(Display * , XErrorEvent * )
+{
+  XWindow::_shmError = true;
+}
+#endif
+
 XWindow::XWindow()
 {
   // initialize class variables
@@ -1065,18 +1074,26 @@
     _XShmInfo.readOnly = False;
 
     // Attaching the shared memory to the display
-    if (!XShmAttach (_display, &_XShmInfo)) {
+    XErrorHandler oldHandler = XSetErrorHandler((XErrorHandler) catchXShmError);
+    Status status = XShmAttach (_display, &_XShmInfo);
+    XSync(_display, False);
+    XSetErrorHandler((XErrorHandler) oldHandler);
+
+    if ( (status != True) || (_shmError) ) {
       XDestroyImage(_XImage);
       _XImage = NULL;
-      if (_XShmInfo.shmaddr != ((char *) -1))
+      if (_XShmInfo.shmaddr != ((char *) -1)) {
         shmdt(_XShmInfo.shmaddr);
+      }
       PTRACE(1, "X11\t  XShmAttach failed");
+      if ( (status == True) && (_shmError) ) {
+        PTRACE(1, "X11\t  X server supports SHM but apparently we are remotely connected...");
+      }
       _useShm = false;
     } 
   } 
 
   if (_useShm) {
-    XSync(_display, False);
     shmctl(_XShmInfo.shmid, IPC_RMID, 0);
   }
 }

Modified: trunk/lib/gui/xwindow.h
==============================================================================
--- trunk/lib/gui/xwindow.h	(original)
+++ trunk/lib/gui/xwindow.h	Sat Sep 13 08:24:49 2008
@@ -130,6 +130,10 @@
   virtual void RegisterSlave (XWindow *slave) { _slave = slave; };
 
   virtual void SetSwScalingAlgo (unsigned int algorithm) { _scalingAlgorithm = algorithm; };
+
+#ifdef HAVE_SHM
+  static bool _shmError;
+#endif
 protected:
   Display *_display;
   Window _rootWindow;

Modified: trunk/src/gui/main.cpp
==============================================================================
--- trunk/src/gui/main.cpp	(original)
+++ trunk/src/gui/main.cpp	Sat Sep 13 08:24:49 2008
@@ -2713,11 +2713,12 @@
     return FALSE;
 
   display_info.gc = GDK_GC_XGC(mw->video_widget_gc);
+  display_info.xdisplay = GDK_GC_XDISPLAY (mw->video_widget_gc);
+
   display_info.window = GDK_WINDOW_XWINDOW (mw->main_video_image->window);
   if (display_info.window == 0)  //FIXME: Should be None
     return FALSE;
 
-  display_info.xdisplay = GDK_DISPLAY ();
   gdk_flush();
 #endif
   display_info.widget_info_set = TRUE;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]