rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / x11 / libdga / src / mbsmemb_update.c
bloba8ab135d4d5803de8f1aecf2a19909d84568de7c
1 /* Copyright (c) 1993, 1999, Oracle and/or its affiliates. All rights reserved.
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice (including the next
11 * paragraph) shall be included in all copies or substantial portions of the
12 * Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
26 ** mbsmemb_update.c
28 ** Routines of the update phase that apply equally to both types of
29 ** multibuffer set members, windows and multibuffers.
32 #include <stdio.h>
33 #include <sys/types.h>
34 #ifdef SERVER_DGA
35 #include <X11/Xlib.h>
36 #endif /* SERVER_DGA */
37 #include "dga_incls.h"
38 #include "pix_grab.h"
39 #include "mbufsetstr.h"
41 static void dgai_mbsmemb_notifySiteChg (_Dga_window dgawin);
42 static void dgai_mbsmemb_notifyMbChg (_Dga_window dgawin);
43 static void dgai_mbsmemb_notifyOvlState (_Dga_window dgawin);
46 ** The update phase entry routine for mbufset members.
47 ** Called if the master change count of the shared info
48 ** differs from the last recorded count in the client structure.
51 int
52 dgai_mbsmemb_update (Dga_drawable dgadraw, short bufIndex)
54 _Dga_window dgawin = (_Dga_window) dgadraw;
55 int status;
57 #ifdef MT
58 if (dgaMTOn) {
59 mutex_lock(dgawin->mutexp); /* lock the per-window mutex */
60 DGA_LOCK(dgadraw);
61 /* check the real change count that we saved away */
62 if (dgawin->shadow_chngcnt[bufIndex + 1] == *dgawin->s_chngcnt_p) {
63 DGA_UNLOCK(dgadraw);
64 mutex_unlock(dgawin->mutexp);
65 return (0);
68 mutex_lock(&dgaGlobalMutex);
69 #endif
70 /* establish the new real lock subject */
71 dgawin->rLockSubj = bufIndex;
73 /* save last lock subject. This may be used later in the update phase */
74 dgawin->eLockSubjPrev = dgawin->eLockSubj;
76 /* start out assuming we're not aliased. This may change if we detect
77 aliasing later in the update phase */
78 dgawin->eLockSubj = dgawin->rLockSubj;
80 /* the first thing we do is distinguish between locking a window
81 and a multibuffer. The update logic is different */
82 if (bufIndex == -1) {
83 status = dgai_win_update(dgawin, bufIndex);
84 } else {
85 status = dgai_mbuf_update(dgawin, bufIndex);
87 #ifdef MT
88 if (dgaMTOn) {
89 /* save the real change count */
90 dgawin->shadow_chngcnt[bufIndex + 1] =
91 dgawin->c_wm_chngcnt[bufIndex + 1];
92 /* For the MT case, make sure that this update function gets called
93 * the next time around, so overwrite the change count to make it
94 * different.
96 dgawin->c_wm_chngcnt[bufIndex + 1] = *dgawin->s_chngcnt_p - 1;
97 DGA_UNLOCK(dgadraw);
98 mutex_unlock(dgawin->mutexp); /* unlock the per-window mutex */
100 mutex_unlock(&dgaGlobalMutex);
101 #endif
102 return (status);
107 ** See if the shared info of the main window is still valid.
108 ** Nonzero is returned if it is no longer valid and has become
109 ** a zombie.
113 dgai_mbsmemb_syncZombie (_Dga_window dgawin)
115 WXINFO *infop;
117 infop = (WXINFO *) dgawin->w_info;
119 if (infop->w_obsolete) {
120 dgawin->changeMask |= DGA_CHANGE_ZOMBIE;
121 return (1);
122 } else {
123 return (0);
128 ** The way we deal with any composition change is to destroy the old
129 ** multibuffer set and establish a new one.
132 void
133 dgai_mbsmemb_syncMbufset (_Dga_window dgawin)
136 DgaMbufSetPtr pMbs;
137 WXINFO *infop;
139 /* check to see if this is an actual composition change or simply
140 a display change */
141 if (dgawin->c_mbcomposseq == *dgawin->s_mbcomposseq_p) {
142 /* no change -- must be only a display change */
143 return;
146 /* this is a real composition change. Destroy the old mbufset (if any)
147 and create a new one */
149 infop = (WXINFO *) dgawin->w_info;
150 pMbs = dgawin->pMbs;
152 /* remember whether window was previously multibuffered. This is
153 used later in the update phase to determine the reason for the
154 mbufset change */
155 dgawin->prevWasMbuffered = (pMbs != NULL);
157 /* destroy the old one */
158 if (pMbs) {
159 dgai_mbufset_decref(pMbs);
160 dgawin->pMbs = NULL;
163 dgawin->c_mbcomposseq = *dgawin->s_mbcomposseq_p;
165 if (!infop->w_mbsInfo.enabled) {
166 return;
169 /* create a new one */
170 pMbs = dgai_mbufset_create(dgawin);
172 if (!pMbs) {
173 /* TODO: really the only way we have of responding to this is treat
174 it as a zombie. It's not ideal, but what else can we do? */
175 dgawin->changeMask |= DGA_CHANGE_ZOMBIE;
178 dgawin->pMbs = pMbs;
183 ** If a render buffer notification function has been registered
184 ** and the current effective lock subject differs from the current
185 ** write buffer, call the notification function to change the render
186 ** buffer state.
189 void
190 dgai_mbsmemb_syncRendBuf (_Dga_window dgawin)
192 WXINFO *infop;
193 short *pRendBuf;
195 infop = (WXINFO *) dgawin->w_info;
197 /* has client registered the notification function? */
198 if (!dgawin->rendBufNotifyFunc) {
199 return;
202 /* we only need to notify in single-address access mode */
203 if (infop->w_mbsInfo.accessMode != DGA_MBACCESS_SINGLEADDR) {
204 return;
208 * Only notify if rend buf is different from what we want it to be
209 * Note: we treat the write buffer index as the render buffer and ignore
210 * the read buffer index.
212 pRendBuf = &infop->wx_dbuf.write_buffer;
213 if (*pRendBuf != dgawin->eLockSubj) {
214 (*dgawin->rendBufNotifyFunc)((Dga_drawable)dgawin, dgawin->eLockSubj,
215 dgawin->rendBufNotifyClientData);
217 /* update the shared info so both the server and other clients can
218 see and react to the change */
219 *pRendBuf = dgawin->eLockSubj;
224 ** A derivative change is one which is dependent on changes discovered
225 ** earlier in the update phase (i.e. the basic changes). We determine here which ones need
226 ** to be reported. Derivative changes may be reported along with
227 ** the basic changes. The derivative changes in common for mbufset
228 ** members are: site change.
231 void
232 dgai_mbsmemb_figureDerivChgs (_Dga_window dgawin)
234 /* safety */
235 dgawin->siteChgReason = DGA_SITECHG_UNKNOWN;
237 /* check for zombie */
238 if (dgawin->changeMask & DGA_CHANGE_ZOMBIE) {
239 /* report both a site change and a clip for zombies. This is simply
240 more insurance that the client will sync up with the null clip. */
241 dgawin->changeMask |= (DGA_CHANGE_SITE | DGA_CHANGE_CLIP);
242 dgawin->siteChgReason = DGA_SITECHG_ZOMBIE;
243 return;
246 /* check for first time */
247 if ((dgawin->eLockSubj == -1) && !dgawin->prevLocked) {
248 dgawin->changeMask |= DGA_CHANGE_SITE;
249 dgawin->siteChgReason = DGA_SITECHG_INITIAL;
250 dgawin->prevLocked = 1;
251 return;
252 } else if ((dgawin->eLockSubj >= 0) &&
253 !dgawin->pMbs->prevLocked[(int)dgawin->eLockSubj]) {
254 dgawin->changeMask |= DGA_CHANGE_SITE;
255 dgawin->siteChgReason = DGA_SITECHG_INITIAL;
256 dgawin->pMbs->prevLocked[dgawin->eLockSubj] = 1;
257 return;
260 /* check for cache change */
261 if (dgawin->changeMask & DGA_CHANGE_CACHE) {
262 dgawin->changeMask |= DGA_CHANGE_SITE;
263 dgawin->siteChgReason = DGA_SITECHG_CACHE;
264 return;
267 /* check for alias change */
268 if (dgawin->changeMask & DGA_CHANGE_ALIAS) {
269 dgawin->changeMask |= DGA_CHANGE_SITE;
270 dgawin->siteChgReason = DGA_SITECHG_ALIAS;
271 return;
274 /* check for mbufset composition change */
275 if (dgawin->changeMask & DGA_CHANGE_MBUFSET) {
276 dgawin->changeMask |= DGA_CHANGE_SITE;
277 dgawin->siteChgReason = DGA_SITECHG_MB;
278 return;
284 ** If we can report any changes through notification, do so now.
287 void
288 dgai_mbsmemb_notify (_Dga_window dgawin)
290 /* report any mbufset change */
291 if (dgawin->changeMask & DGA_CHANGE_MBUFSET) {
292 dgai_mbsmemb_notifyMbChg(dgawin);
295 if (dgawin->changeMask & DGA_CHANGE_SITE) {
296 dgai_mbsmemb_notifySiteChg(dgawin);
299 if (dgawin->changeMask & DGA_CHANGE_OVLSTATE) {
300 dgai_mbsmemb_notifyOvlState(dgawin);
303 /* there are no notify functions for the following:
304 clip, cursor, bstore, cache */
307 void
308 dgai_mbsmemb_devinfo_update(_Dga_window dgawin)
310 if (!DGA_LOCKSUBJ_VALID(dgawin, dgawin->eLockSubj) ||
311 dgawin->changeMask & DGA_CHANGE_ZOMBIE) {
312 return;
315 if (DGA_LOCKSUBJ_WINDOW(dgawin, dgawin->eLockSubj)) {
316 /* check for window devinfo change */
317 if (dgawin->c_devinfoseq != *dgawin->s_devinfoseq_p) {
318 dgawin->changeMask |= DGA_CHANGE_DEVINFO;
319 dgawin->c_devinfoseq = *dgawin->s_devinfoseq_p;
321 } else if (!DGA_LOCKSUBJ_VIEWABLE(dgawin, dgawin->eLockSubj)) {
322 /* check for nonviewable mbuf devinfo change */
323 dgai_nmbuf_devinfo_update(dgawin);
326 /* Note: viewable mbufs don't have dev info */
329 static void
330 dgai_mbsmemb_notifySiteChg (_Dga_window dgawin)
332 if (dgawin->siteNotifyFunc) {
333 (*dgawin->siteNotifyFunc)((Dga_drawable)dgawin, dgawin->eLockSubj,
334 dgawin->siteNotifyClientData,
335 dgawin->siteChgReason);
336 dgawin->changeMask &= ~DGA_CHANGE_SITE;
337 dgawin->siteChgReason = DGA_SITECHG_UNKNOWN;
338 } else {
339 /* client must find out through dga_draw_sitechg */
344 static void
345 dgai_mbsmemb_notifyMbChg (_Dga_window dgawin)
347 /* figure out reason for change */
348 if (!dgawin->prevWasMbuffered && dgawin->pMbs) {
349 dgawin->mbChgReason = DGA_MBCHG_ACTIVATION;
350 } else if (dgawin->prevWasMbuffered && !dgawin->pMbs) {
351 dgawin->mbChgReason = DGA_MBCHG_DEACTIVATION;
352 } else if (dgawin->prevWasMbuffered && dgawin->pMbs) {
353 dgawin->mbChgReason = DGA_MBCHG_REPLACEMENT;
354 } else {
355 /* this might happen if the mbufset was activated and then, in
356 the same update phase, deactivated. In this case, allow it,
357 but just don't report any changes */
358 dgawin->changeMask &= ~DGA_CHANGE_MBUFSET;
359 dgawin->mbChgReason = DGA_MBCHG_UNKNOWN;
360 return;
363 if (dgawin->mbNotifyFunc) {
364 (*dgawin->mbNotifyFunc)((Dga_drawable)dgawin,
365 dgawin->mbNotifyClientData,
366 dgawin->mbChgReason);
367 dgawin->changeMask &= ~DGA_CHANGE_MBUFSET;
368 dgawin->mbChgReason = DGA_MBCHG_UNKNOWN;
369 } else {
370 /* client must find out through dga_draw_mbchg */
375 static void
376 dgai_mbsmemb_notifyOvlState (_Dga_window dgawin)
378 if (dgawin->ovlStateNotifyFunc) {
379 (*dgawin->ovlStateNotifyFunc)((Dga_drawable)dgawin,
380 dgawin->ovlStateNotifyClientData,
381 dgawin->c_ovlstate);
382 dgawin->changeMask &= ~DGA_CHANGE_OVLSTATE;
383 } else {
384 /* client must find out through dga_draw_sitechg */