summaryrefslogtreecommitdiffstats
path: root/opensuse/core/qt3/0080-net-wm-sync-request.patch
blob: b3e23cd1351be65f22d988c1dab79ab1f8910b0a (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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
This qt-copy patch has been slightly modified to apply to the SUSE package
(does not apply directly because of the immodule patch).

--- src/kernel/qwidget_x11.cpp.sav	2007-08-29 15:04:42.000000000 +0200
+++ src/kernel/qwidget_x11.cpp	2007-08-29 15:06:17.000000000 +0200
@@ -85,6 +85,12 @@ static QWidget *keyboardGrb = 0;
 extern Time qt_x_time;
 extern Time qt_x_user_time;
 
+#ifndef QT_NO_XSYNC
+extern Atom qt_net_wm_sync_request_counter;
+extern Atom qt_net_wm_sync_request;
+extern bool qt_use_xsync;
+#endif
+
 // defined in qfont_x11.cpp
 extern bool qt_has_xft;
 
@@ -593,11 +599,14 @@ void QWidget::create( WId window, bool i
 
 	XResizeWindow( dpy, id, crect.width(), crect.height() );
 	XStoreName( dpy, id, qAppName() );
-	Atom protocols[4];
+	Atom protocols[5];
 	int n = 0;
 	protocols[n++] = qt_wm_delete_window;	// support del window protocol
 	protocols[n++] = qt_wm_take_focus;	// support take focus window protocol
 	protocols[n++] = qt_net_wm_ping;	// support _NET_WM_PING protocol
+#ifndef QT_NO_XSYNC
+	protocols[n++] = qt_net_wm_sync_request;// support the _NET_WM_SYNC_REQUEST protocol
+#endif
 	if ( testWFlags( WStyle_ContextHelp ) )
 	    protocols[n++] = qt_net_wm_context_help;
 	XSetWMProtocols( dpy, id, protocols, n );
@@ -623,6 +632,14 @@ void QWidget::create( WId window, bool i
 	XChangeProperty(dpy, id, qt_net_wm_pid, XA_CARDINAL, 32, PropModeReplace,
 			(unsigned char *) &curr_pid, 1);
 
+#ifndef QT_NO_XSYNC
+        // set _NET_WM_SYNC_COUNTER
+        createSyncCounter();
+        long counterVal = topData()->syncCounter;
+        XChangeProperty( dpy, id, qt_net_wm_sync_request_counter, XA_CARDINAL, 32, PropModeReplace,
+                         (unsigned char*) &counterVal, 1);
+#endif
+
 	// when we create a toplevel widget, the frame strut should be dirty
 	fstrut_dirty = 1;
 
@@ -722,6 +739,9 @@ void QWidget::destroy( bool destroyWindo
 	    if ( destroyWindow )
 		qt_XDestroyWindow( this, x11Display(), winid );
 	}
+#ifndef QT_NO_XSYNC
+        destroySyncCounter();
+#endif
 	setWinId( 0 );
 
 	extern void qPRCleanup( QWidget *widget ); // from qapplication_x11.cpp
@@ -781,6 +801,10 @@ void QWidget::reparentSys( QWidget *pare
         destroyInputContext();
     }
 
+#ifndef QT_NO_XSYNC
+    destroySyncCounter();
+#endif
+
     if ( isTopLevel() || !parent ) // we are toplevel, or reparenting to toplevel
         topData()->parentWinId = 0;
 
@@ -2464,6 +2488,11 @@ void QWidget::createTLSysExtra()
     // created lazily
     extra->topextra->xic = 0;
 #endif
+#ifndef QT_NO_XSYNC
+    extra->topextra->syncCounter = 0;
+    extra->topextra->syncRequestValue[0] = 0;
+    extra->topextra->syncRequestValue[1] = 0;
+#endif
 }
 
 void QWidget::deleteTLSysExtra()
@@ -2510,6 +2539,51 @@ void QWidget::checkChildrenDnd()
     }
 }
 
+
+#ifndef QT_NO_XSYNC
+// create a window's XSyncCounter
+void QWidget::createSyncCounter()
+{
+    if( !qt_use_xsync || !isTopLevel() || topData()->syncCounter )
+        return;
+    XSyncValue zero;
+    XSyncIntToValue( &zero, 0 );
+    topData()->syncCounter = XSyncCreateCounter( x11Display(), zero );
+}
+
+// destroy a window's XSyncCounter
+void QWidget::destroySyncCounter()
+{
+    if( !qt_use_xsync || !extra || !extra->topextra
+        || !extra->topextra->syncCounter )
+        return;
+    XSyncDestroyCounter( x11Display(), extra->topextra->syncCounter );
+    extra->topextra->syncCounter = 0;
+}
+
+// increment a window's XSyncCounter
+void QWidget::incrementSyncCounter()
+{
+    if( qt_use_xsync && topData()->syncCounter &&
+        !(topData()->syncRequestValue[0] == 0 &&
+         topData()->syncRequestValue[1] == 0) ) {
+        XSyncValue val;
+        XSyncIntsToValue( &val, topData()->syncRequestValue[ 0 ], topData()->syncRequestValue[ 1 ] );
+        XSyncSetCounter( x11Display(), topData()->syncCounter, val );
+        topData()->syncRequestValue[0] = topData()->syncRequestValue[1] = 0;
+    }
+}
+
+// handle _NET_WM_SYNC_REQUEST
+void QWidget::handleSyncRequest( void* ev )
+{
+    XEvent* xev = (XEvent*)ev;
+    topData()->syncRequestValue[ 0 ] = xev->xclient.data.l[ 2 ];
+    topData()->syncRequestValue[ 1 ] = xev->xclient.data.l[ 3 ];
+}
+#endif  // QT_NO_XSYNC
+
+
 /*!
     \property QWidget::acceptDrops
     \brief whether drop events are enabled for this widget
--- src/kernel/qt_x11_p.h.sav	2007-08-29 15:04:42.000000000 +0200
+++ src/kernel/qt_x11_p.h	2007-08-29 15:05:27.000000000 +0200
@@ -174,6 +174,11 @@ extern "C" {
 #endif // QT_NO_XRENDER
 
 
+#ifndef QT_NO_XSYNC
+#  include <X11/extensions/sync.h>
+#endif // QT_NO_XSYNC
+
+
 #ifndef QT_NO_XKB
 #  include <X11/XKBlib.h>
 #endif // QT_NO_XKB
--- src/kernel/qwidget.h.sav	2007-08-29 15:04:42.000000000 +0200
+++ src/kernel/qwidget.h	2007-08-29 15:05:52.000000000 +0200
@@ -605,6 +605,14 @@ private:
     void	 focusInputContext();
     void	 unfocusInputContext();
     void	 checkChildrenDnd();
+
+#ifndef QT_NO_XSYNC
+    void        createSyncCounter();
+    void        destroySyncCounter();
+    void        incrementSyncCounter();
+    void        handleSyncRequest( void* ev );
+#endif
+
 #elif defined(Q_WS_MAC)
     uint    own_id : 1, macDropEnabled : 1;
     EventHandlerRef window_event;
@@ -986,6 +994,10 @@ struct Q_EXPORT QTLWExtra {
 #if defined(QT_NO_IM_EXTENSIONS)
     void    *xic;				// Input Context
 #endif
+#ifndef QT_NO_XSYNC
+    ulong    syncCounter;
+    uint     syncRequestValue[2];
+#endif
 #endif
 #if defined(Q_WS_MAC)
     WindowGroupRef group;
--- src/kernel/qapplication_x11.cpp.sav	2007-08-29 15:04:42.000000000 +0200
+++ src/kernel/qapplication_x11.cpp	2007-08-29 15:05:27.000000000 +0200
@@ -288,6 +288,11 @@ Atom		*qt_net_supported_list	= 0;
 Window		*qt_net_virtual_root_list	= 0;
 
 
+// X11 SYNC support
+#ifndef QT_NO_XSYNC
+Atom		qt_net_wm_sync_request_counter	= 0;
+Atom		qt_net_wm_sync_request     	= 0;
+#endif
 
 // client leader window
 Window qt_x11_wm_client_leader = 0;
@@ -312,6 +317,13 @@ static int xrandr_eventbase;
 // Display
 Q_EXPORT bool qt_use_xrender = FALSE;
 
+#ifndef QT_NO_XSYNC
+// True if SYNC extension exists on the connected display
+bool qt_use_xsync = FALSE;
+static int xsync_eventbase;
+static int xsync_errorbase;
+#endif
+
 // modifier masks for alt/meta - detected when the application starts
 static long qt_alt_mask = 0;
 static long qt_meta_mask = 0;
@@ -2007,6 +2019,11 @@ void qt_init_internal( int *argcptr, cha
 	qt_x11_intern_atom( "UTF8_STRING", &qt_utf8_string );
         qt_x11_intern_atom( "_SGI_DESKS_MANAGER", &qt_sgi_desks_manager );
 
+#ifndef QT_NO_XSYNC
+	qt_x11_intern_atom( "_NET_WM_SYNC_REQUEST_COUNTER", &qt_net_wm_sync_request_counter );
+	qt_x11_intern_atom( "_NET_WM_SYNC_REQUEST", &qt_net_wm_sync_request );
+#endif
+
 	qt_xdnd_setup();
 	qt_x11_motifdnd_init();
 
@@ -2043,6 +2060,15 @@ void qt_init_internal( int *argcptr, cha
 	}
 #endif // QT_NO_XRENDER
 
+#ifndef QT_NO_XSYNC
+	// Try to initialize SYNC extension on the connected display
+	int xsync_major, xsync_minor;
+	if ( XSyncQueryExtension( appDpy, &xsync_eventbase, &xsync_errorbase ) && 
+	     XSyncInitialize( appDpy, &xsync_major,  &xsync_minor ) ) {
+	     qt_use_xsync = TRUE;
+	}
+#endif 
+
 #ifndef QT_NO_XKB
 	// If XKB is detected, set the GrabsUseXKBState option so input method
 	// compositions continue to work (ie. deadkeys)
@@ -3196,6 +3222,10 @@ int QApplication::x11ClientMessage(QWidg
 		    XSendEvent( event->xclient.display, event->xclient.window,
 				False, SubstructureNotifyMask|SubstructureRedirectMask, event );
 		}
+#ifndef QT_NO_XSYNC
+	    } else if (a == qt_net_wm_sync_request ) {
+		    widget->handleSyncRequest( event );
+#endif
 	    }
 	} else if ( event->xclient.message_type == qt_qt_scrolldone ) {
 	    widget->translateScrollDoneEvent(event);
@@ -5818,6 +5848,21 @@ bool QETWidget::translateScrollDoneEvent
     return FALSE;
 }
 
+#if defined(Q_C_CALLBACKS)
+extern "C" {
+#endif
+#ifndef QT_NO_XSYNC
+static Bool qt_net_wm_sync_request_scanner(Display*, XEvent* event, XPointer arg)
+{
+    return (event->type == ClientMessage && event->xclient.window == *(Window*)arg
+        && event->xclient.message_type == qt_wm_protocols
+        && event->xclient.data.l[ 0 ] == qt_net_wm_sync_request );
+}
+#endif
+
+#if defined(Q_C_CALLBACKS)
+}
+#endif
 
 //
 // ConfigureNotify (window move and resize) event translation
@@ -5849,6 +5894,7 @@ bool QETWidget::translateConfigEvent( co
         if (! extra || extra->compress_events) {
             // ConfigureNotify compression for faster opaque resizing
             XEvent otherEvent;
+            int compressed_configs = 0;
             while ( XCheckTypedWindowEvent( x11Display(), winId(), ConfigureNotify,
                                             &otherEvent ) ) {
                 if ( qt_x11EventFilter( &otherEvent ) )
@@ -5869,7 +5915,18 @@ bool QETWidget::translateConfigEvent( co
                     newCPos.ry() = otherEvent.xconfigure.y +
                                    otherEvent.xconfigure.border_width;
                 }
+                ++compressed_configs;
+            }
+#ifndef QT_NO_XSYNC
+            // _NET_WM_SYNC_REQUEST compression 
+            Window wid = winId();
+            while ( compressed_configs &&
+                    XCheckIfEvent( x11Display(), &otherEvent,
+                    qt_net_wm_sync_request_scanner, (XPointer)&wid ) ) {
+                handleSyncRequest( (void*)&otherEvent );
+                --compressed_configs;
             }
+#endif
         }
 
 	QRect cr ( geometry() );
@@ -5923,6 +5980,8 @@ bool QETWidget::translateConfigEvent( co
 	repaint( !testWFlags(WResizeNoErase) || transbg );
     }
 
+    incrementSyncCounter();
+
     return TRUE;
 }