aboutsummaryrefslogtreecommitdiff
path: root/debian/patches/120_nxagent_libcairo-null-source-drawables.full.patch
blob: 319f6ed3b4884da272197e0d221c00d84936bd6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
Description: Fix nxagent/x2goagent With New LibCairo (>1.12.1)
 Quoting two postings of Jim Burnes <jvburnes@gmail.com> on x2go-dev ML:

 I don't know what the current patch status is for fixing nxagent with the
 new libcairo (1.12.1+ I believe), but eventually I got tired of waiting and
 created my own patches for nxagent/x2goagent.

 Most of the fixes were required because the render extension now allows
 (and libcairo uses) null source drawables (for gradients etc), null masks
 and null mask drawables.

 This change creates a bit of a logic mess in the code.   Previous patches
 to the code tried to account for all of the possibilities, but fell a
 little short.

 Consider this an alpha-quality patch.  I've only tested it in KDE while
 running GTK applications.   All my favorite GTK apps like Firefox, Emacs,
 rox-filer and all my other GTK apps that were broken are now working just
 fine.  (Though I'm getting only the standard GTK look and feel - don't know
 if that's caused by anything I've done.)

 Could someone test this under Gnome?

 Also, since I'm not primarily an X software engineer I'd like a specialist
 to take a look at it.   The fix is a little crude.   I just attached to the
 x2goagent process and fixed the lines that caused segfaults.   (About 10 of
 them).

 I also rewrote one of the macros in Pixels.h into a local subroutine in
 Render.c.  It had a bug in it and complex macro bugs are a PITA to debug in
 gdb (or anything else really).   The macro is only used in one place and
 although the code in the macro is called pretty often, it's very likely
 that the compiler would inline it anyway.  The rewrite increases
 readability by a large factor.

 A better patch could be created by someone that understands nxagent and X
 much better.   The render extension code receives render ops from X client
 programs.  The render ops can contain any combination of picture source,
 picture destination and picture mask.  It's apparently legal to send render
 ops with combinations of null picture source drawables, picture masks and
 picture mask drawables.   A better way to patch this would be to simply
 perform a return on all the illegal combinations of null parameters for the
 render ops.  That way you wouldn't have to keep re-checking the parameter
 values.

 So anyway, here it is.  I appreciate it if someone out there would test it
 and let me know.   Also if anyone knows of the X docs which discuss null
 picture sources and masks in the render extension I'd be glad to create a
 cleaner patch that conforms to the stands.


 You can reproduce the issue by running any recent copy of x2go/nxagent and
 start any program that uses very recent versions of libCairo.  Things
 started breaking for both ArchLinux and Debian SID users about 3 weeks ago.

 The issues started with versions of libCairo >= libcairo2_1.12.0-2_amd64
 (debian packages of course).  These versions of Cairo seem to use null
 parameters in render ops a lot.   Users of recent GTK environments would
 have the startup process just crash.  KDE sessions start and run fine until
 you start a gtk app.
Forwarded: pending
Author: Jim Burnes <jvburnes@gmail.com>
Last-Update: 2012-05-11
--- a/nx-X11/programs/Xserver/hw/nxagent/Render.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/Render.c
@@ -995,6 +995,36 @@
   #endif
 }
 
+
+int nxagentShouldDeferComposite(PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
+{
+
+int drawableDst;
+int linkDeferred;
+int unSyncedSrcMask;
+
+	drawableDst      =  ( nxagentRenderVersionMajor == 0 &&
+	                      nxagentRenderVersionMinor == 8 &&
+		              (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP
+                            );
+
+	linkDeferred     =  ( nxagentOption(DeferLevel) >= 2 &&
+                              nxagentOption(LinkType) < LINK_TYPE_ADSL
+                            );
+
+	unSyncedSrcMask  =  ( nxagentOption(DeferLevel) == 1 &&
+                              (pDst) -> pDrawable -> type == DRAWABLE_PIXMAP &&
+                              (
+			       (pSrc -> pDrawable && (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)) ||
+	                       ((pMask) && pMask -> pDrawable && (nxagentDrawableStatus((pMask) -> pDrawable) == NotSynchronized))
+			      )
+			    );
+
+
+	return drawableDst || linkDeferred || unSyncedSrcMask;
+}
+
+
 void nxagentComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
                           INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, INT16 xDst,
                               INT16 yDst, CARD16 width, CARD16 height)
@@ -1036,8 +1066,8 @@
   }
 
   #endif
-
-  if (NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst))
+  /* if (NXAGENT_SHOULD_DEFER_COMPOSITE(pSrc, pMask, pDst)) */
+  if (nxagentShouldDeferComposite(pSrc, pMask, pDst))
   {
     pDstRegion = nxagentCreateRegion(pDst -> pDrawable, NULL, xDst, yDst, width, height);
 
@@ -1095,7 +1125,8 @@
     }
   }
 
-  if (pMask != NULL && pMask -> pDrawable != pSrc -> pDrawable &&
+  if ((pMask) && (pMask->pDrawable) &&
+          pMask -> pDrawable != pSrc -> pDrawable &&
           pMask -> pDrawable != pDst -> pDrawable)
   {
     nxagentSynchronizeShmPixmap(pMask -> pDrawable, xMask, yMask, width, height);
@@ -1259,7 +1290,7 @@
    * on the real X server.
    */
 
-  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  if (pSrc -> pDrawable && (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized))
   {
     #ifdef TEST
     fprintf(stderr, "nxagentGlyphs: Synchronizing source [%s] at [%p].\n",
@@ -1302,14 +1333,15 @@
       nxagentSynchronizeBox(pSrc -> pDrawable, &glyphBox, NEVER_BREAK);
     }
 
-    if (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP)
+    if (pSrc -> pDrawable && (pSrc -> pDrawable -> type == DRAWABLE_PIXMAP))
     {
       nxagentIncreasePixmapUsageCounter((PixmapPtr) pSrc -> pDrawable);
     }
   }
 
-  if (pSrc -> pDrawable != pDst -> pDrawable &&
-          nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized)
+
+  if (pSrc -> pDrawable && (pSrc -> pDrawable != pDst -> pDrawable &&
+          nxagentDrawableStatus(pDst -> pDrawable) == NotSynchronized))
   {
     #ifdef TEST
     fprintf(stderr, "nxagentGlyphs: Synchronizing destination [%s] at [%p].\n",
@@ -1749,7 +1781,9 @@
     return;
   }
 
-  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+  /* the following blocks need fixing to ignore null values of pDrawable */
+
+  if (pSrc -> pDrawable && (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized))
   {
     #ifdef TEST
     fprintf(stderr, "nxagentTrapezoids: Going to synchronize the source drawable at [%p].\n",
@@ -1843,7 +1877,9 @@
    * operation like nxagentTrapezoids() does.
    */
 
-  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+
+
+  if (pSrc -> pDrawable && (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized))
   {
     #ifdef TEST
     fprintf(stderr, "nxagentTriangles: Going to synchronize the source drawable at [%p].\n",
@@ -1920,7 +1956,8 @@
    * operation like nxagentTrapezoids() does.
    */
 
-  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+
+  if (pSrc -> pDrawable && (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized))
   {
     #ifdef TEST
     fprintf(stderr, "nxagentTriStrip: Going to synchronize the source drawable at [%p].\n",
@@ -1997,7 +2034,8 @@
    * operation like nxagentTrapezoids() does.
    */
 
-  if (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized)
+
+  if (pSrc -> pDrawable && (nxagentDrawableStatus(pSrc -> pDrawable) == NotSynchronized))
   {
     #ifdef TEST
     fprintf(stderr, "nxagentTriFan: Going to synchronize the source drawable at [%p].\n",