vim: update to 9.1.1086
[oi-userland.git] / components / x11 / libdga / src / win_grab.c
blob66d771833aecac65bcdcc04eb374f609f09f7e3b
1 /* Copyright (c) 1993, 2015, 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.
24 /*
25 * win_grab.c - the client side code for DGA window grabber
28 /****
31 * Shared window synchronization routines - client side
35 * Functions:
37 * Dga_window
38 * dga_win_grab(devfd, token)
39 * int devfd ;
40 * Dga_token token ;
42 * Grab a window. 'token' is the window-info handle returned by
43 * XDgaGrabWindow. 'devfd' is the file descriptor of the frame buffer
44 * if known, -1 otherwise. If you specify -1, dga_win_grab will open the
45 * frame buffer. The frame buffer fd may be inquired from the returned
46 * Dga_window structure via the dga_win_devfd() routine.
48 * Returns a pointer to the a struct dga_window on success, NULL on
49 * failure.
53 * dga_win_ungrab(infop, cflag)
54 * Dga_window infop ;
55 * int cflag ;
57 * Ungrab a window. All resources allocated by dga_win_grab are freed.
58 * If 'cflag' is nonzero, the framebuffer fd described for the device
59 * is also closed.
61 * The application should call XDgaUnGrabWindow(dpy,win) after
62 * calling dga_win_ungrab() so that the server may free the window-info
63 * page at the other end.
67 * short *
68 * dga_win_clipinfo(win)
69 * Dga_window win ;
71 * Returns pointer to cliplist. Replaces old wx_sh_clipinfo_c() macro.
75 * char *
76 * dga_win_fbname(win)
77 * Dga_window win ;
79 * Returns name of fb. Replaces old wx_devname_c() macro.
83 * int
84 * dga_win_clipchg(win)
85 * Dga_window win ;
87 * Returns 1 if cliplist changed since last call. Replaces old
88 * wx_modif_c() and wx_seen_c() macros.
92 * int
93 * dga_win_curschg(win)
94 * Dga_window win ;
96 * Returns 1 if cursor changed since last call.
100 * int
101 * dga_win_rtnchg(win)
102 * Dga_window win ;
104 * Returns 1 if retained info changed since last call.
108 * int
109 * dga_win_devfd(win)
110 * Dga_window win ;
112 * Returns framebuffer fd.
116 * dga_win_bbox(win, xp, yp, widthp, heightp)
117 * Dga_window win;
118 * int *xp, *yp, *widthp, *heightp;
120 * Returns window bounding box
124 * int
125 * dga_win_singlerect(win)
126 * Dga_window win;
128 * Returns nonzero if the window is a single rectangle.
132 * int
133 * dga_win_empty(win)
134 * Dga_window win;
136 * Returns nonzero if the window is empty.
140 * int
141 * dga_win_obscured(win)
142 * Dga_window win;
144 * Returns nonzero if the window is obscured.
148 * int
149 * dga_win_cursactive(win)
150 * Dga_window win;
152 * Returns nonzero if the cursor grabber is active.
156 * void
157 * dga_win_cursupdate(win, func, data)
158 * Dga_window win;
159 * void (*func)();
160 * void* data;
162 * Decide if the cursor needs to be taken down, and if so, call
163 * (*func)(data, win, x, y, mem)
164 * void* data ;
165 * Dga_window win ;
166 * int x,y ;
167 * Dga_curs_mpr *mem ;
171 * Dga_dbinfo *
172 * dga_win_dbinfop(win)
173 * Dga_window win;
175 * Return dbinfo pointer.
179 * Dga_widinfo *
180 * dga_win_widinfop(win)
181 * Dga_window win;
183 * Return window id info pointer.
185 * dga_win_depth(win)
186 * Dga_window win;
188 * Return windows depth .
191 * dga_win_borderwidth(win)
192 * Dga_window win;
194 * Return windows borderwidth .
196 * void
197 * dga_win_set_client_infop(win, client_info_ptr)
198 * Dga_window win;
199 * void* client_info_ptr;
200 * Sets a client specific pointer in Dga_window
203 * dga_win_get_client_infop(win)
204 * Dga_window win;
205 * Returns the client specific pointer
207 ****/
208 #include <stdio.h>
209 #include <unistd.h>
210 #include <fcntl.h>
211 #include <sys/types.h>
212 #ifdef SERVER_DGA
213 #include <X11/X.h>
214 #include <X11/Xmd.h>
215 #include "windowstr.h"
216 #include "dga_externaldefs.h"
217 #include "dga/dgawinstr.h"
218 #else
219 #include <sys/file.h>
220 #include <sys/mman.h>
221 #include <sys/ioctl.h>
222 #include <errno.h>
223 #include <X11/Xlib.h>
224 #include <stdlib.h>
225 #include <unistd.h>
226 #include <string.h>
228 #ifdef SVR4
229 #include <sys/fbio.h>
230 #include <sys/fcntl.h>
231 #else
232 #include <sun/fbio.h>
233 #include <fcntl.h>
234 #endif
235 #endif /* SERVER_DGA */
237 #include "dga_incls.h"
238 #include "rtn_grab.h"
240 #define GRABFILE "/tmp/wg"
241 #define CURGFILE "/tmp/curg"
242 #define NDIGITS 8
244 #define MINSHMEMSIZE (8*1024)
245 #define MAXSHMEMSIZE (0x00040000)
246 #define WX_PAGESZ (8*1024)
248 #if 0
249 #ifdef DEBUG
250 extern int sys_nerr;
251 extern char *sys_errlist[] ;
252 #endif
253 #endif
255 extern int _dga_winlockat(u_long cookie, int **lockp, int **unlockp);
256 extern int _dga_winlockdt(int *lockp, int *unlockp);
258 /* Some structure definition for internal bookkeeping */
259 typedef struct dga_winlist {
260 Dga_token w_token; /* Token associated with win */
261 struct dga_window *dga_clientplist;/*List of client ptrs in win */
262 struct dga_window *dga_clientplist_draw; /* List of client ptrs in win
263 * using drawable i/f. */
264 struct dga_winlist *next_winlist; /* Next link in the dga list */
265 #ifdef MT
266 mutex_t mutex;
267 #endif
269 } *Dga_winlist;
271 static struct dga_winlist *dga_wlist = NULL;
273 static int dga_win_update(Dga_drawable dgawin);
274 static int dgai_win_initMbufset (_Dga_window dgawin);
275 static void release_lockpages(int devfd, _Dga_window clientp);
276 static _Dga_window check_other_curg_windows(WXINFO *);
277 void dgai_win_ungrab_common(_Dga_window dgawin, int cflag,int drawableGrabber);
278 int dgai_win_check_multiple_grab(_Dga_window dgawin, int drawableGrabber);
279 void safe_free_clientp(_Dga_window clientp);
281 /*bug fix for 4248958: use safe_free_client() to replace free() */
282 void
283 safe_free_clientp(clientp)
284 _Dga_window clientp;
287 if(clientp){
288 if(clientp->back) free(clientp->back);
289 if(clientp->depth) free(clientp->depth);
290 if(clientp->stencil) free(clientp->stencil);
291 if(clientp->accum) free(clientp->accum);
292 if(clientp->alpha) free(clientp->alpha);
293 free(clientp);
297 /******************************************
299 * dgai_win_grab_common:
301 * create shared memory file for window information
302 * map to lock page
304 * arguments:
306 * int devfd; INPUT
307 * file descriptor of graphics device
309 * Dga_token token; INPUT
310 * magic cookie supplied by the server
312 * returns a user virtual address for a dga_window structure.
313 * returns NULL if anything goes awry.
315 * 'devfd' is the file descriptor of the frame buffer, if known,
316 * -1 otherwise. If you specify -1, wx_grab will open the
317 * frame buffer. The frame buffer fd may be inquired from the returned
318 * Dga_window ptr to the struct dga_window via the dga_win_devfd() routine.
320 *****************************************/
324 ** Shared between both drawable grabber and window compatibility interface.
327 Dga_window
328 dgai_win_grab_common (Display *dpy, int devfd, Dga_token token, int drawableGrabber)
330 WXINFO *infop;
331 _Dga_window clientp = NULL;
332 Dga_winlist wlist;
333 int lockfd ;
334 Dga_lockp lockp, unlockp ;
335 char filename[sizeof(GRABFILE)+NDIGITS+1];
336 int filefd;
337 int locktype ;
338 int i;
339 #ifdef SERVER_DGA
340 WindowPtr pWin;
341 Window win;
343 if (!_dga_is_X_window(token, &dpy, &win)) {
344 return NULL;
346 pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
347 #endif /* SERVER_DGA */
349 /* First, check if already grabbed by this client. Note that we
350 always treat the new drawable and old window grabbers separately */
351 for(wlist = dga_wlist;wlist != NULL;wlist = wlist->next_winlist) {
352 if (wlist->w_token == token) {
353 _Dga_window orig_clientp,new_clientp;
355 /* If multiple clients are grabbing the same
356 * window, then we duplicate the per client info
357 * structure and return that instead of the original
358 * allocated clientp structure. Also remember to add
359 * this new info structure to the linked list. This
360 * change obsoletes the w_grab_count field which
361 * will always be equal to 1
364 if ((new_clientp =
365 (_Dga_window) malloc(sizeof(struct dga_window))) == NULL)
366 return NULL ;
368 if (drawableGrabber) {
369 if (wlist->dga_clientplist_draw)
370 orig_clientp = wlist->dga_clientplist_draw;
371 else
372 orig_clientp = wlist->dga_clientplist;
373 *new_clientp = *orig_clientp;
374 new_clientp->w_lockcnt =0;
375 new_clientp->w_grab_count =1;
377 if (wlist->dga_clientplist_draw) {
378 /* Add it to the list of clientp structure associated
379 * with this window */
381 new_clientp->w_next = orig_clientp;
382 } else {
384 /* Need to initialize all drawableGrabber
385 * specific data. */
387 infop = (WXINFO *)new_clientp->w_info;
388 if (infop->info_sz != sizeof(WXINFO)) {
389 /* mismatch on 64 bit port or other trouble */
390 fprintf(stderr,
391 "wx_grab: mismatch on shared WXINFO size info page is %d sizeof is %d \n",
392 infop->info_sz, sizeof(WXINFO));
393 free(new_clientp);
394 return(NULL);
396 new_clientp->drawable_type = DGA_DRAW_WINDOW;
397 new_clientp->w_update_func =
398 (int(*)())dgai_mbsmemb_update;
399 new_clientp->c_mbufseq = 0;
400 new_clientp->s_mbufseq_p = &infop->w_mbsInfo.mbufseq;
401 new_clientp->c_mbcomposseq = 0;
402 new_clientp->s_mbcomposseq_p =
403 &infop->w_mbsInfo.compositionseq;
404 new_clientp->s_devinfoseq_p = &infop->w_devinfoseq;
405 new_clientp->c_devinfoseq = 0;
406 new_clientp->siteNotifyFunc = NULL;
407 new_clientp->siteNotifyClientData = NULL;
408 new_clientp->mbNotifyFunc = NULL;
409 new_clientp->mbNotifyClientData = NULL;
410 new_clientp->rendBufNotifyFunc = NULL;
411 new_clientp->rendBufNotifyClientData = NULL;
412 new_clientp->rLockSubj = DGA_LOCKSUBJ_INVALID;
413 new_clientp->eLockSubj = DGA_LOCKSUBJ_INVALID;
414 new_clientp->eLockSubjPrev = DGA_LOCKSUBJ_INVALID;
415 new_clientp->changeMask = 0;
416 new_clientp->prevWasMbuffered = 0;
417 new_clientp->mbChgReason = DGA_MBCHG_UNKNOWN;
418 new_clientp->siteChgReason = DGA_SITECHG_UNKNOWN;
419 new_clientp->prevLocked = 0;
420 if ((dpy != NULL) && drawableGrabber) {
421 if (!dgai_win_initMbufset(new_clientp)) {
422 dga_win_ungrab(new_clientp, 0);
425 new_clientp->w_next = NULL;
427 wlist->dga_clientplist_draw = new_clientp;
429 /* the same mbufset is shared between all client
430 * structures for this window */
432 if (orig_clientp->pMbs) {
433 dgai_mbufset_incref(orig_clientp->pMbs);
435 #ifdef MT
436 new_clientp->mutexp = &wlist->mutex;
437 /* Same window was grabbed 2 or more times via the
438 * drawable interface so turn per-drawable MT
439 * locking on if we are linked with -lthread also.
441 if (dgaThreaded) {
442 /* Currently, this variable gets set to 1 and
443 * never gets turned off. This could be optimized
444 * if needed.
446 dgaMTOn = 1;
448 #endif
449 return new_clientp;
451 } else {
452 if (wlist->dga_clientplist)
453 orig_clientp = wlist->dga_clientplist;
454 else
455 orig_clientp = wlist->dga_clientplist_draw;
456 *new_clientp = *orig_clientp;
457 new_clientp->w_update_func = dga_win_update;
458 new_clientp->w_lockcnt =0;
459 new_clientp->w_grab_count =1;
461 if (wlist->dga_clientplist) {
462 /* Add it to the list of clientp structure associated
463 * with this window */
464 new_clientp->w_next = orig_clientp;
465 } else {
466 new_clientp->w_next = NULL;
468 wlist->dga_clientplist = new_clientp;
469 #ifdef MT
470 new_clientp->mutexp = &wlist->mutex;
471 #endif
472 return new_clientp;
478 if( (clientp =
479 (_Dga_window) malloc(sizeof(struct dga_window))) == NULL )
480 return NULL ;
481 memset(clientp, 0, sizeof(struct dga_window));
483 #ifdef SERVER_DGA
485 /* Now get a pointer to the shared info page from
486 * pWin's private data */
488 DgaSetupWindow(pWin);
489 WDEV *wdev;
491 wdev = pDgaWindow->pDgaWdev;
492 infop = (WXINFO *)wdev->infop;
493 if (infop == NULL) return NULL;
495 #else
496 sprintf(filename, "%s%08x", GRABFILE, token);
498 if ((filefd = open(filename,O_RDWR,0666))<0) {
499 safe_free_clientp(clientp) ;
500 return((Dga_window)NULL);
503 /* map the wx_winfo area */
504 infop = (WXINFO *)mmap(0,
505 MAXSHMEMSIZE,
506 PROT_READ|PROT_WRITE,
507 MAP_SHARED,
508 filefd,
509 (off_t)0);
511 if (infop == (WXINFO *)-1) {
512 close(filefd);
513 safe_free_clientp(clientp) ;
514 return((Dga_window)NULL);
516 if (infop->info_sz != sizeof(WXINFO)) {
517 /* mismatch on 64 bit port or other trouble */
518 #ifdef DEBUG
519 fprintf(stderr,
520 "wx_grab: mismatch on WXINFO size info page is %d sizeof is %d \n",
521 infop->info_sz, sizeof(WXINFO));
522 #endif
523 munmap((caddr_t)infop, MAXSHMEMSIZE) ;
524 close(filefd) ;
525 safe_free_clientp(clientp) ;
526 return(NULL);
529 /* open the frame buffer if not already opened by client */
530 if( devfd >= 0 )
531 lockfd = devfd ;
532 else {
533 lockfd = open(infop->w_devname, O_RDWR,0666) ;
534 if( lockfd < 0 ) {
535 #ifdef DEBUG
536 fprintf(stderr, "wx_grab: cannot open %s, %s\n",
537 infop->w_devname, strerror(errno)) ;
538 #endif
539 munmap((caddr_t)infop, MAXSHMEMSIZE) ;
540 close(filefd) ;
541 safe_free_clientp(clientp) ;
542 return NULL ;
545 #endif /* SERVER_DGA */
547 if (drawableGrabber) {
548 clientp->drawable_type = DGA_DRAW_WINDOW;
550 clientp->w_dpy = dpy;
551 clientp->w_info = (void*)infop ;
552 clientp->w_infofd = 0; /* no longer needed */
553 clientp->w_next = NULL;
555 clientp->curs_info = NULL; /* must set up here, may be changed below */
556 clientp->curs_fd = -1;
558 #ifdef SERVER_DGA
559 clientp->w_devfd = infop->w_sdevfd; ;
560 clientp->w_lockp = (Dga_lockp)infop->w_slockp;
561 clientp->w_unlockp = (Dga_lockp)infop->w_slockp;
563 clientp->w_lib_private = (void *) infop; /* PRIVATE DATA */
564 #else
565 clientp->w_devfd = lockfd ;
566 lockp = NULL; /* init to NULL for check below */
567 unlockp = NULL;
569 /* On cursor-grabbed devices, find out if we already have a
570 * lockp, unlockp, and cursor page mapping for this device.
571 * We don't want to grab the same lockpage, etc. twice.
573 if (infop->w_version >= 2 && infop->c_sinfo) {
574 _Dga_window winp;
576 winp = check_other_curg_windows(infop);
577 if (winp) {
578 clientp->curs_fd = winp->curs_fd;
579 clientp->curs_info = winp->curs_info;
580 lockp = winp->w_lockp;
581 unlockp = winp->w_unlockp;
585 if (lockp == NULL) {
586 /* only get new lock pages if necessary */
587 locktype = infop->w_version >= 2 ? infop->w_locktype : WG_LOCKDEV ;
588 switch( locktype ) {
589 case WG_LOCKDEV:
590 /* map the lock page */
591 lockp = (Dga_lockp)mmap(0,
592 WX_PAGESZ,
593 PROT_READ|PROT_WRITE,
594 MAP_SHARED,
595 lockfd,(off_t)infop->w_cookie);
597 if (lockp == (Dga_lockp)-1) {
598 #ifdef DEBUG
599 fprintf(stderr, "wx_grab: cannot map lock page, %s\n",
600 strerror(errno)) ;
601 #endif
602 munmap((caddr_t)infop, MAXSHMEMSIZE) ;
603 close(filefd);
604 if( devfd < 0 )
605 close(lockfd) ;
606 safe_free_clientp(clientp) ;
607 return(NULL);
610 /* map the unlock page */
611 unlockp = (Dga_lockp)mmap(0,
612 WX_PAGESZ,
613 PROT_READ|PROT_WRITE,
614 MAP_SHARED,
615 lockfd,(off_t)infop->w_cookie) ;
617 if(unlockp == (Dga_lockp)-1) {
618 #ifdef DEBUG
619 fprintf(stderr, "wx_grab: cannot map unlock page\n") ;
620 #endif
621 munmap((caddr_t)lockp, WX_PAGESZ) ;
622 munmap((caddr_t)infop, MAXSHMEMSIZE) ;
623 close(filefd);
624 if( devfd < 0 )
625 close(lockfd) ;
626 safe_free_clientp(clientp) ;
627 return(NULL);
629 break ;
631 case WG_WINLOCK:
632 if( _dga_winlockat(infop->w_cookie, &lockp, &unlockp) != 0 ) {
633 munmap((caddr_t)infop, MAXSHMEMSIZE);
634 close(filefd);
635 if( devfd < 0 )
636 close(lockfd) ;
637 safe_free_clientp(clientp) ;
638 return(NULL);
640 break ;
644 clientp->w_lockp = lockp ;
645 clientp->w_unlockp = unlockp ;
647 /* cursor grabber stuff */
648 if ((infop->w_version >= 2) && (infop->c_sinfo) &&
649 ((clientp->curs_fd == -1) || (clientp->curs_info == NULL))) {
650 char cfn[sizeof(CURGFILE)+NDIGITS+1];
651 int curs_fd;
653 strcpy(cfn,CURGFILE);
654 sprintf(cfn+sizeof(CURGFILE)-1,"%08x", infop->c_filesuffix);
656 /* open the shared cursor page */
657 if ((curs_fd = open(cfn, O_RDWR,0666))<0) {
658 #ifdef DEBUG
659 fprintf(stderr, "wx_grab: cannot open cursor grabber page\n") ;
660 #endif
661 release_lockpages(devfd, clientp);
662 return((Dga_window)NULL);
664 clientp->curs_fd = curs_fd;
666 /* Map it */
667 clientp->curs_info = (caddr_t) mmap(0,
668 MINSHMEMSIZE,
669 PROT_READ|PROT_WRITE,
670 MAP_SHARED,
671 curs_fd,
672 (off_t)0);
674 if (clientp->curs_info == (caddr_t) -1) {
675 #ifdef DEBUG
676 fprintf(stderr, "wx_grab: cannot map cursor page, %s\n",
677 strerror(errno)) ;
678 #endif
679 close(curs_fd);
680 release_lockpages(devfd, clientp);
681 return(NULL);
683 /* check to see if you have a good magic number */
684 if (((Dga_cursinfo *) (clientp->curs_info))->c_magic !=
685 DGA_CURG_MAGIC) {
686 #ifdef DEBUG
687 fprintf(stderr, "wx_grab: wrong cursor page mapped, %s\n",
688 strerror(errno)) ;
689 #endif
690 munmap(clientp->curs_info, MINSHMEMSIZE) ;
691 close(curs_fd);
692 release_lockpages(devfd, clientp);
693 return(NULL);
696 #endif /* SERVER_DGA */
698 /* success, fill out rest of structure */
699 clientp->w_token = token;
700 clientp->w_client = 0 ;
701 clientp->c_clipseq = 0 ;
702 clientp->s_clipseq_p = &(infop->u.vn.w_clipseq) ;
703 if (drawableGrabber) {
704 clientp->w_update_func = (int(*)())dgai_mbsmemb_update;
705 } else {
706 /* compatibility */
707 clientp->w_update_func = dga_win_update;
709 #ifdef MT
710 if (dgaThreaded) {
711 clientp->w_unlock_func = dgai_unlock;
712 } else {
713 clientp->w_unlock_func = NULL;
715 #else
716 clientp->w_lock_func = NULL;
717 clientp->w_unlock_func = NULL;
718 #endif
719 clientp->w_lockcnt = 0;
720 if (infop->w_version != 0) {
721 clientp->w_clipptr = (short *)((char *)infop+infop->u.vn.w_clipoff);
722 clientp->w_cliplen = 0;
724 if (infop->w_version < 2) {
725 clientp->c_chngcnt = 0;
726 clientp->s_chngcnt_p = clientp->s_clipseq_p;
727 } else {
728 clientp->c_chngcnt = 0;
729 clientp->s_chngcnt_p = &(infop->w_chng_cnt);
730 for (i = 0; i < DGA_MAX_GRABBABLE_BUFS + 1; i ++) {
731 clientp->c_wm_chngcnt[i] = 0;
732 #ifdef MT
733 clientp->shadow_chngcnt[i] = 0;
734 #endif
737 /* Now initialize the next field to pt to the second member of
738 * c_wm_chngcnt array - this is specifically for performance
739 * tuning of the lock macro
741 clientp->w_wm_2nd = clientp->c_wm_chngcnt + 1;
743 if ((infop->w_version < 2) || (clientp->curs_info == NULL)) {
744 clientp->s_curseq_p = &clientp->c_curseq;
745 clientp->c_curseq = 0;
746 } else {
747 clientp->s_curseq_p =
748 &(((Dga_cursinfo *) (clientp->curs_info))->c_chng_cnt);
749 clientp->c_curseq =
750 ((Dga_cursinfo *) (clientp->curs_info))->c_chng_cnt - 1;
751 /* so first test of dga_win_curschg will see a change */
754 clientp->back = (void *)malloc(sizeof(dga_internal_buffer_rec));
755 if ( !clientp->back )
756 return NULL;
758 clientp->depth = (void *)malloc(sizeof(dga_internal_buffer_rec));
759 if ( !clientp->depth )
760 return NULL;
762 clientp->stencil = (void *)malloc(sizeof(dga_internal_buffer_rec));
763 if ( !clientp->stencil )
764 return NULL;
766 clientp->accum = (void *)malloc(sizeof(dga_internal_buffer_rec));
767 if ( !clientp->accum )
768 return NULL;
770 clientp->alpha = (void *)malloc(sizeof(dga_internal_buffer_rec));
771 if ( !clientp->alpha )
772 return NULL;
774 ((dga_internal_buffer)clientp->back)->bufferp = NULL;
775 ((dga_internal_buffer)clientp->depth)->bufferp = NULL;
776 ((dga_internal_buffer)clientp->stencil)->bufferp = NULL;
777 ((dga_internal_buffer)clientp->accum)->bufferp = NULL;
778 ((dga_internal_buffer)clientp->alpha)->bufferp = NULL;
780 ((dga_internal_buffer)clientp->back)->pDraw = (Dga_drawable)clientp;
781 ((dga_internal_buffer)clientp->depth)->pDraw = (Dga_drawable)clientp;
782 ((dga_internal_buffer)clientp->stencil)->pDraw = (Dga_drawable)clientp;
783 ((dga_internal_buffer)clientp->accum)->pDraw = (Dga_drawable)clientp;
784 ((dga_internal_buffer)clientp->alpha)->pDraw = (Dga_drawable)clientp;
786 ((dga_internal_buffer)clientp->back)->buf_size = 0;
787 ((dga_internal_buffer)clientp->depth)->buf_size = 0;
788 ((dga_internal_buffer)clientp->stencil)->buf_size = 0;
789 ((dga_internal_buffer)clientp->accum)->buf_size = 0;
790 ((dga_internal_buffer)clientp->alpha)->buf_size = 0;
792 clientp->buf_resize_flag = 0;
793 clientp->c_buffer_swap = 0;
795 clientp->db_enabled = 0;
796 clientp->c_rtnseq = 0;
797 clientp->s_rtnseq_p = &clientp->c_rtnseq;
798 clientp->rtn_info = NULL;
799 clientp->rtn_flags = 0;
801 /* initialization for drawable grabber code */
802 clientp->pMbs = NULL;
803 if (drawableGrabber) {
804 clientp->c_mbufseq = 0;
805 clientp->s_mbufseq_p = &infop->w_mbsInfo.mbufseq;
806 clientp->c_mbcomposseq = 0;
807 clientp->s_mbcomposseq_p = &infop->w_mbsInfo.compositionseq;
808 clientp->s_devinfoseq_p = &infop->w_devinfoseq;
809 clientp->c_devinfoseq = 0;
810 clientp->siteNotifyFunc = NULL;
811 clientp->siteNotifyClientData = NULL;
812 clientp->mbNotifyFunc = NULL;
813 clientp->mbNotifyClientData = NULL;
814 clientp->rendBufNotifyFunc = NULL;
815 clientp->rendBufNotifyClientData = NULL;
816 clientp->rLockSubj = DGA_LOCKSUBJ_INVALID;
817 clientp->eLockSubj = DGA_LOCKSUBJ_INVALID;
818 clientp->eLockSubjPrev = DGA_LOCKSUBJ_INVALID;
819 clientp->changeMask = 0;
820 clientp->prevWasMbuffered = 0;
821 clientp->mbChgReason = DGA_MBCHG_UNKNOWN;
822 clientp->siteChgReason = DGA_SITECHG_UNKNOWN;
823 clientp->prevLocked = 0;
826 /* add to linked list of grabbed windows - for internal bookkeeping
827 * Note: this should be done last in order for other code, e.g.
828 * check_other_curg_windows() to work correctly
830 if (!dga_wlist) {
832 if ((dga_wlist =
833 (Dga_winlist) malloc(sizeof(struct dga_winlist))) == NULL )
834 return NULL ;
835 dga_wlist->w_token = token;
836 if (drawableGrabber) {
837 dga_wlist->dga_clientplist_draw = clientp;
838 dga_wlist->dga_clientplist = NULL;
839 } else {
840 dga_wlist->dga_clientplist_draw = NULL;
841 dga_wlist->dga_clientplist = clientp;
843 dga_wlist->next_winlist = NULL;
844 } else {
845 struct dga_winlist *new_wlist;
847 if ((new_wlist =
848 (Dga_winlist) malloc(sizeof(struct dga_winlist))) == NULL )
849 return NULL;
850 new_wlist->w_token = token;
851 if (drawableGrabber) {
852 new_wlist->dga_clientplist_draw = clientp;
853 new_wlist->dga_clientplist = NULL;
854 } else {
855 new_wlist->dga_clientplist_draw = NULL;
856 new_wlist->dga_clientplist = clientp;
858 new_wlist->next_winlist = dga_wlist;
859 dga_wlist = new_wlist;
861 #ifndef SERVER_DGA
862 close(filefd) ;
863 #endif /* SERVER_DGA */
865 #ifdef MT
866 mutex_init(&dga_wlist->mutex, USYNC_THREAD, NULL);
867 clientp->mutexp = &dga_wlist->mutex;
868 #endif
870 /* If window is multibuffered, initialize multibuffer set */
871 /* If window is being grabbed through the old interface don't
872 * init the mbufset since mbuffers where not supported int
873 * older versions of DGA */
874 if ((dpy != NULL) && drawableGrabber) {
875 if (!dgai_win_initMbufset(clientp)) {
876 dga_win_ungrab(clientp, 0);
880 return((Dga_window)clientp);
884 Dga_window
885 dga_win_grab(devfd, token)
886 int devfd;
887 Dga_token token;
889 /* Call the common grab routine with dpy == NULL to signify that
890 * mbuffers are not to be initialized. */
892 return (dgai_win_grab_common(NULL, devfd, token, 0));
896 #ifndef SERVER_DGA
897 static _Dga_window
898 check_other_curg_windows(infop)
899 WXINFO *infop;
901 Dga_winlist winp;
902 _Dga_window clientp;
903 WXINFO *linfop;
905 for(winp = dga_wlist; winp != NULL; winp = winp->next_winlist) {
906 if (clientp = winp->dga_clientplist_draw) {
907 linfop = (WXINFO *) clientp->w_info;
908 if (strcmp(linfop->w_devname, infop->w_devname) == 0) {
909 return(clientp);
912 if (clientp = winp->dga_clientplist) {
913 linfop = (WXINFO *) clientp->w_info;
914 if (strcmp(linfop->w_devname, infop->w_devname) == 0) {
915 return(clientp);
919 return NULL;
923 static void
924 release_lockpages(devfd, clientp)
925 int devfd ;
926 _Dga_window clientp;
928 int lockfd = clientp->w_devfd ;
929 WXINFO *infop = (WXINFO *) clientp->w_info ;
930 Dga_lockp lockp = clientp->w_lockp ;
931 Dga_lockp unlockp = clientp->w_unlockp ;
932 int locktype ;
934 if ((clientp->curs_info ||
935 ((infop->w_version >= 2) && (infop->c_sinfo))) &&
936 ((check_other_curg_windows(infop) != NULL) ||
937 (check_other_curg_windows(infop) == NULL && infop->w_devname[0] == 0))) {
938 /* don't free lock pages
939 * Note: check both clientp->curs_info and infop->c_sinfo because
940 * this routine is called both at grab and ungrab time. Client
941 * may not have set curs_info non-zero at grab time. Server may
942 * set c_sinfo NULL at window destroy time.
944 } else {
945 locktype = infop->w_version >= 2 ? infop->w_locktype : WG_LOCKDEV ;
946 switch(locktype ) {
947 case WG_LOCKDEV:
948 munmap((caddr_t)lockp, WX_PAGESZ) ;
949 munmap((caddr_t)unlockp, WX_PAGESZ) ;
950 break ;
951 case WG_WINLOCK:
952 (void) _dga_winlockdt((int *)lockp, (int *)unlockp) ;
953 break ;
956 if( devfd < 0 )
957 close(lockfd) ;
958 munmap((caddr_t)infop, MAXSHMEMSIZE) ;
959 safe_free_clientp(clientp) ;
961 #endif /* SERVER_DGA */
963 void
964 dga_win_ungrab(clientpi, cflag)
965 Dga_window clientpi;
966 int cflag ;
968 _Dga_window clientp = (struct dga_window *)clientpi;
970 dgai_win_ungrab_common(clientpi,cflag, 0);
973 void
974 dgai_win_ungrab_common(clientp, cflag,drawableGrabber)
975 _Dga_window clientp;
976 int cflag ;
977 int drawableGrabber;
980 WXINFO *infop = (WXINFO *) clientp->w_info ;
981 int infofd, devfd , curs_fd, match;
982 struct dga_winlist *prevwinp, *winp;
984 /* remove from linked list of grabbed windows
985 * Note: this should be done first in order for other code, e.g.
986 * check_other_curg_windows() to work correctly
988 match = 0;
989 winp = dga_wlist;
990 prevwinp = NULL;
991 while (winp) {
992 if (winp->w_token == clientp->w_token) {
993 struct dga_window *clntp, *prevclntp;
994 if (drawableGrabber)
995 clntp = winp->dga_clientplist_draw;
996 else
997 clntp = winp->dga_clientplist;
999 prevclntp = NULL;
1000 while (clntp) {
1001 if (clntp == clientp) {
1002 match = 1;
1003 if( prevclntp )
1004 prevclntp->w_next = clntp->w_next;
1005 else {
1006 if (drawableGrabber)
1007 winp->dga_clientplist_draw = clntp->w_next;
1008 else
1009 winp->dga_clientplist = clntp->w_next;
1011 break;
1013 prevclntp = clntp;
1014 clntp = clntp->w_next;
1016 if (!match) {
1017 /* Check for old style clients */
1018 clntp = winp->dga_clientplist;
1019 prevclntp = NULL;
1020 while (clntp) {
1021 if (clntp == clientp) {
1022 match = 1;
1023 if( prevclntp )
1024 prevclntp->w_next = clntp->w_next;
1025 else {
1026 if (drawableGrabber)
1027 winp->dga_clientplist_draw = clntp->w_next;
1028 else
1029 winp->dga_clientplist = clntp->w_next;
1031 break;
1033 prevclntp = clntp;
1034 clntp = clntp->w_next;
1037 break ;
1039 prevwinp = winp;
1040 winp = winp->next_winlist;
1043 if (!match)
1044 return; /* error */
1046 /* TODO: do this for every client, or only once? */
1047 if ((clientp->rtn_flags & RTN_GRABBED) && (!winp->dga_clientplist))
1048 dga_rtn_ungrab(clientp);
1049 if (clientp->db_enabled && (!winp->dga_clientplist))
1050 dga_db_release(clientp);
1051 devfd = clientp->w_devfd ;
1053 #ifndef SERVER_DGA
1054 /* Cursor grabber stuff */
1055 /* TODO: do this for every client, or only once? */
1056 if ((clientp->curs_info) && (check_other_curg_windows(infop) == NULL) &&
1057 (!infop->c_sinfo)) {
1058 curs_fd = clientp->curs_fd;
1059 munmap(clientp->curs_info, MINSHMEMSIZE) ;
1060 close(curs_fd);
1062 #endif /* SERVER_DGA */
1064 /* deref any associated multibuffer set */
1065 if (clientp->pMbs) {
1066 dgai_mbufset_decref(clientp->pMbs);
1067 clientp->pMbs = NULL;
1070 /* TODO: shouldn't we free the clientp??? */
1071 /* Now check to see if all that needs to be freed has been freed */
1072 if ((winp->dga_clientplist_draw == NULL) &&
1073 (winp->dga_clientplist == NULL)){
1074 #ifndef SERVER_DGA
1075 release_lockpages( cflag ? -1 : 0, clientp ) ;
1076 #endif /* SERVER_DGA */
1077 /* Then free this node and unlink it from the list */
1078 if( prevwinp != NULL )
1079 prevwinp->next_winlist = winp->next_winlist ;
1080 else
1081 dga_wlist = winp->next_winlist ;
1082 #ifdef MT
1083 mutex_destroy(&winp->mutex);
1084 #endif
1085 free(winp);
1090 dgai_win_check_multiple_grab(clientp, drawableGrabber)
1091 _Dga_window clientp;
1094 struct dga_winlist *winp;
1095 int match;
1097 /* Checking to see if this client is grabbing a multiply grabbed
1098 * window
1100 match = 0;
1101 winp = dga_wlist;
1103 while (winp) {
1104 if (winp->w_token == clientp->w_token) {
1105 /* Now we have the correct window */
1106 struct dga_window *clntp, *prevclntp;
1108 if (drawableGrabber)
1109 clntp = winp->dga_clientplist_draw;
1110 else
1111 clntp = winp->dga_clientplist;
1113 prevclntp = NULL;
1114 while (clntp) {
1115 /* Now we have the correct client */
1116 if (clntp == clientp) {
1117 /* Check to see if there are any more... */
1118 if (prevclntp || clntp->w_next) {
1119 match = 1;
1120 break;
1123 prevclntp = clntp;
1124 clntp = clntp->w_next;
1126 if (match) break;
1128 winp = winp->next_winlist;
1130 return match;
1133 short *
1134 dga_win_clipinfo(wini)
1135 Dga_window wini ;
1137 _Dga_window win = (struct dga_window *)wini;
1138 WXINFO *infop = (WXINFO *) win->w_info ;
1140 if (wx_shape_flags(infop) & DGA_SH_RECT_FLAG)
1141 return((short *)&((struct class_SHAPE_vn *)((char *)(infop) +
1142 (infop)->u.vn.w_shapeoff))->SHAPE_YMIN);
1143 return(win->w_clipptr);
1147 char *
1148 dga_win_fbname(wini)
1149 Dga_window wini;
1151 _Dga_window win = (struct dga_window *)wini;
1153 return(((WXINFO *) (win->w_info))->w_devname);
1157 dga_win_clipchg(wini)
1158 Dga_window wini;
1160 _Dga_window win = (struct dga_window *)wini;
1162 if (win->c_clipseq != *(win->s_clipseq_p)) {
1163 ((WXINFO *) win->w_info)->w_flag &= ~WMODIF;
1164 win->c_clipseq = *(win->s_clipseq_p);
1165 return 1;
1167 return 0;
1171 dga_win_curschg(wini)
1172 Dga_window wini;
1174 _Dga_window win = (struct dga_window *)wini;
1176 if (win->c_curseq != *(win->s_curseq_p)) {
1177 win->c_curseq = *(win->s_curseq_p);
1178 return 1;
1180 return 0;
1184 dga_win_rtnchg(wini)
1185 Dga_window wini;
1187 _Dga_window win = (struct dga_window *)wini;
1188 if ((win->rtn_flags & RTN_GRABBED) && !(win->rtn_flags & RTN_MAPPED)) {
1189 /* rtn grabbed, but not currently mapped */
1190 if (win->rtn_flags & RTN_MAPCHG) {
1191 /* just went unmapped */
1192 win->rtn_flags &= ~RTN_MAPCHG;
1193 return 1;
1195 return 0;
1197 /* otherwise either not rtn grabbed or have a rtn mapping */
1198 if (win->c_rtnseq != *(win->s_rtnseq_p)) {
1199 win->c_rtnseq = *(win->s_rtnseq_p);
1200 return 1;
1202 return 0;
1206 dga_win_devfd(wini)
1207 Dga_window wini;
1209 _Dga_window win = (struct dga_window *)wini;
1210 return(win->w_devfd);
1213 void
1214 dga_win_bbox(wini, xp, yp, widthp, heightp)
1215 Dga_window wini;
1216 int *xp, *yp, *widthp, *heightp;
1218 _Dga_window win = (struct dga_window *)wini;
1219 WXINFO *infop = (WXINFO *) win->w_info;
1221 if (infop->w_version < 2) {
1222 *xp = infop->w_org.x >> 16;
1223 *yp = infop->w_org.y >> 16;
1224 *widthp = infop->w_dim.x >> 16;
1225 *heightp = infop->w_dim.y >> 16;
1226 return;
1228 *xp = infop->w_window_boundary.xleft;
1229 *yp = infop->w_window_boundary.ytop;
1230 *widthp = infop->w_window_boundary.width;
1231 *heightp = infop->w_window_boundary.height;
1235 dga_win_singlerect(wini)
1236 Dga_window wini;
1238 _Dga_window win = (struct dga_window *)wini;
1239 WXINFO *infop = (WXINFO *) win->w_info;
1241 return(wx_shape_flags(infop) & DGA_SH_RECT_FLAG);
1245 dga_win_empty(wini)
1246 Dga_window wini;
1248 _Dga_window win = (struct dga_window *)wini;
1249 WXINFO *infop = (WXINFO *) win->w_info;
1251 return(wx_shape_flags(infop) & DGA_SH_EMPTY_FLAG);
1254 u_char
1255 dga_win_depth(wini)
1256 Dga_window wini;
1258 _Dga_window win = (struct dga_window *)wini;
1259 WXINFO *infop = (WXINFO *) win->w_info;
1261 if (infop->w_version >= 3)
1262 return(infop->w_depth);
1263 else
1264 return 0;
1267 u_short
1268 dga_win_borderwidth(wini)
1269 Dga_window wini;
1271 _Dga_window win = (struct dga_window *)wini;
1272 WXINFO *infop = (WXINFO *) win->w_info;
1274 if (infop->w_version >= 3)
1275 return(infop->w_borderwidth);
1276 else
1277 return 0;
1281 dga_win_obscured(wini)
1282 Dga_window wini;
1284 _Dga_window win = (struct dga_window *)wini;
1285 WXINFO *infop = (WXINFO *) win->w_info;
1286 int xb, yb, wb, hb;
1287 int ytop, ybot, xleft, xright;
1288 int tmp;
1289 short *ptr;
1291 if (wx_shape_flags(infop) & DGA_SH_RECT_FLAG) {
1292 dga_win_bbox(win, &xb, &yb, &wb, &hb);
1293 ptr = dga_win_clipinfo(win);
1294 ytop = *ptr++; ybot = *ptr++; xleft = *ptr++; xright = *ptr++;
1295 if (ytop > ybot) {
1296 tmp = ytop; ytop = ybot; ybot = tmp;
1298 if (xleft > xright) {
1299 tmp = xleft; xleft = xright; xright = tmp;
1301 if ((yb == ytop) && (xb == xleft) &&
1302 (hb == (ybot - ytop)) && (wb == (xright - xleft))) {
1303 return 1;
1306 return 0;
1310 dgai_win_visibility(Dga_window wini)
1312 if (dga_win_empty(wini))
1313 return (DGA_VIS_FULLY_OBSCURED);
1314 /* This routine returns the reverse of what one would think.
1315 * it returns true if the window is unobscured false otherwise. */
1316 else if (!dga_win_obscured(wini))
1317 return (DGA_VIS_PARTIALLY_OBSCURED);
1319 return (DGA_VIS_UNOBSCURED);
1321 /* This will work when we get to R6 but for now the visibility
1322 * entry in the window structure (which is where this comes from)
1323 * is bogus. I looked at the R6 code and it looks like they
1324 * attempted to get this working.
1325 _Dga_window win = (struct dga_window *)wini;
1326 WXINFO *infop = (WXINFO *) win->w_info;
1328 return (infop->w_visibility);
1332 #define ROUNDUP(i) (((i)+WX_PAGESZ-1)&~(WX_PAGESZ-1))
1334 void
1335 dgai_win_clip_update (_Dga_window clientp)
1337 /* Do anything here that may require unlock/relock, because
1338 * it takes so long.
1341 WXINFO *infop = (WXINFO *) clientp->w_info ;
1342 unsigned int cliplen;
1343 short *clipptr;
1344 short *cmclip;
1345 #ifndef SERVER_DGA
1346 char filename[sizeof(GRABFILE)+NDIGITS+1];
1347 int filefd;
1348 #endif /*SERVER_DGA */
1350 cmclip = (short *)((char *)infop+infop->u.vn.w_clipoff);
1352 #ifdef SERVER_DGA
1353 if (infop->w_flag & WEXTEND) { /* server has an extended mapping */
1354 if (clientp->w_clipptr == cmclip) {
1355 clientp->w_cliplen = infop->w_scliplen;
1356 clientp->w_clipptr = (short *)infop->u.vn.w_sclipptr;
1358 } else {
1359 if (clientp->w_clipptr != cmclip) {
1360 clientp->w_clipptr = cmclip;
1363 #else
1364 while(1) {
1365 if (infop->w_flag & WEXTEND) {
1366 /* server has an extended mapping */
1367 if (clientp->w_clipptr == cmclip) {
1368 /* ...and we don't. */
1369 cliplen = infop->w_scliplen;
1370 DGA_UNLOCK(clientp);
1371 sprintf(filename, "%s%08x", GRABFILE, clientp->w_token);
1373 if ((filefd = open(filename,O_RDWR,0666))<0) {
1374 return;
1376 if (ftruncate(filefd,MINSHMEMSIZE+cliplen)<0) {
1377 close(filefd);
1378 return;
1381 close(filefd);
1383 clipptr = (short *)((char *)infop + MINSHMEMSIZE);
1385 DGA_LOCK(clientp);
1386 if ((int)clipptr != -1) {
1387 clientp->w_cliplen = cliplen;
1388 clientp->w_clipptr = clipptr;
1390 continue; /* at while */
1392 if (clientp->w_cliplen != infop->w_scliplen) {
1393 /* ...and we do... but the wrong size. */
1394 cliplen = infop->w_scliplen;
1395 DGA_UNLOCK(clientp);
1396 sprintf(filename, "%s%08x", GRABFILE, clientp->w_token);
1398 if ((filefd = open(filename,O_RDWR,0666))<0) {
1399 return;
1401 if (ftruncate(filefd,MINSHMEMSIZE+cliplen)<0) {
1402 close(filefd);
1403 return;
1405 close(filefd);
1406 clipptr = (short *)((char *)infop + MINSHMEMSIZE);
1408 DGA_LOCK(clientp);
1409 if ((int)clipptr == -1)
1410 clientp->w_clipptr = cmclip;
1411 else {
1412 clientp->w_cliplen = cliplen;
1413 clientp->w_clipptr = clipptr;
1415 continue; /* at while */
1417 } else {
1418 /* server doesn't have an extended mapping */
1419 if (clientp->w_clipptr != cmclip) {
1420 /* ...and we do. */
1421 DGA_UNLOCK(clientp);
1422 sprintf(filename, "%s%08x", GRABFILE, clientp->w_token);
1424 if ((filefd = open(filename,O_RDWR,0666))<0) {
1425 clientp->w_clipptr = cmclip;
1426 return;
1428 if (ftruncate(filefd,MINSHMEMSIZE)<0) {
1429 clientp->w_clipptr = cmclip;
1430 close(filefd);
1431 return;
1433 close(filefd);
1435 DGA_LOCK(clientp);
1436 clientp->w_clipptr = cmclip;
1437 continue; /* at while */
1440 else { ...nor do we
1441 break;
1445 break;
1447 #endif /* SERVER_DGA */
1450 void
1451 dgai_win_curs_update(_Dga_window win)
1453 /* Do anything here that may require unlock/relock, because
1454 * it takes so long.
1456 * We can add code here in the future to remap the cursor page,
1457 * etc., if we want.
1459 return;
1465 * dgai_rtn_update()
1467 * Do anything here that may require unlock/relock, because
1468 * it takes so long. Remap retained info, etc.
1470 * DGA Retained Window Information Update. This function checks that the
1471 * shared retained information structure hasn't become obsolete. If the
1472 * structure is found to be obsolete, this routine attempts to free and
1473 * re-allocate the resources associated with the retained window. Nothing
1474 * is done in the event that the shared retained information is not obsolete.
1476 * Inputs: Dga_window - Pointer to the dga_window structure for which
1477 * the the shared retained info structure is to
1478 * be removed.
1480 * Outputs: None.
1482 * Globals: None.
1484 * Externals: DGA_LOCK() DGA MACRO
1485 * DGA_UNLOCK() DGA MACRO
1486 * RTN_INFOP() DGA MACRO
1487 * _dga_rtn_map()
1488 * _dga_rtn_unmap()
1491 void
1492 dgai_win_rtn_update (_Dga_window clientp)
1494 unsigned int mapped;
1496 #ifdef SERVER_DGA
1497 mapped = clientp->rtn_flags & RTN_MAPPED;
1498 if (mapped && RTN_INFOP(clientp)->obsolete) {
1499 /* mapped, but obsolete */
1500 (void) _dga_rtn_unmap(clientp);
1501 (void) _dga_rtn_map(clientp);
1504 if (!mapped && (((WXINFO *) clientp->w_info)->w_srtndlink != NULL)) {
1505 /* unmapped on client side, but server has valid w_srtndlink */
1506 (void) _dga_rtn_map(clientp);
1508 #else
1509 while (1) {
1510 mapped = clientp->rtn_flags & RTN_MAPPED;
1511 if (mapped && RTN_INFOP(clientp)->obsolete) {
1512 /* mapped, but obsolete */
1513 DGA_UNLOCK(clientp);
1514 (void) _dga_rtn_unmap(clientp);
1515 (void) _dga_rtn_map(clientp);
1516 DGA_LOCK(clientp);
1517 continue;
1519 if (!mapped && (((WXINFO *) clientp->w_info)->w_srtndlink != NULL)) {
1520 /* unmapped on client side, but server has valid w_srtndlink */
1521 DGA_UNLOCK(clientp);
1522 (void) _dga_rtn_map(clientp);
1523 DGA_LOCK(clientp);
1524 continue;
1526 break;
1528 #endif /* SERVER_DGA */
1532 static int
1533 dga_win_update(wini)
1534 Dga_window wini;
1536 _Dga_window win = (struct dga_window *)wini;
1537 WXINFO *infop = (WXINFO *) win->w_info;
1538 unsigned int sav_clipseq, sav_curseq, sav_rtnseq;
1540 /* establish the new real lock subject */
1541 win->rLockSubj = -1;
1543 /* save last lock subject. This may be used later in the update phase */
1544 win->eLockSubjPrev = win->eLockSubj;
1546 /* start out assuming we're not aliased. This may change if we detect
1547 aliasing later in the update phase */
1548 win->eLockSubj = win->rLockSubj;
1550 /* Do anything here that may require unlock/relock, because
1551 * it takes so long. Also, update win->c_chngcnt.
1554 sav_clipseq = win->c_clipseq;
1555 sav_curseq = win->c_curseq;
1556 sav_rtnseq = win->c_rtnseq;
1557 do {
1558 /* repeat update functions as needed
1559 * through possible unlock/relocks
1561 if (sav_clipseq != *win->s_clipseq_p) {
1562 dgai_win_clip_update(win);
1563 sav_clipseq = *win->s_clipseq_p;
1565 if (sav_curseq != *win->s_curseq_p) {
1566 dgai_win_curs_update(win);
1567 sav_curseq = *win->s_curseq_p;
1569 if ((sav_rtnseq != *win->s_rtnseq_p) ||
1570 ((win->rtn_flags & RTN_GRABBED) &&
1571 !(win->rtn_flags & RTN_MAPPED))) {
1572 dgai_win_rtn_update(win);
1573 sav_rtnseq = *win->s_rtnseq_p;
1575 } while ((sav_clipseq != *win->s_clipseq_p) ||
1576 (sav_curseq != *win->s_curseq_p) ||
1577 (sav_rtnseq != *win->s_rtnseq_p));
1579 if (infop->w_version < 2) {
1580 /* pre OWV3 */
1581 win->c_chngcnt = *win->s_chngcnt_p;
1582 return 1;
1583 } else {
1584 /* post OWV3 beta */
1585 win->c_chngcnt = *win->s_chngcnt_p;
1586 return 1;
1591 dga_win_cursactive(wini)
1592 Dga_window wini;
1594 _Dga_window win = (struct dga_window *)wini;
1595 if (win->curs_info)
1596 return 1;
1597 return 0;
1600 void
1601 dga_win_cursupdate(wini, func, data)
1602 Dga_window wini;
1603 void (*func)();
1604 void* data;
1606 _Dga_window win = (struct dga_window *)wini;
1607 /* assumes the window is already locked */
1609 Dga_cursinfo *curgp = (Dga_cursinfo *) (win->curs_info);
1610 Dga_curs_mpr *curg_mpr;
1611 Dga_curs_memimage curg_mem;
1612 int x, y, w, h;
1614 if ((curgp == 0) || (curgp->c_state_flag != DGA_CURSOR_UP))
1615 return;
1617 curg_mpr = (Dga_curs_mpr *) ((char *) curgp + curgp->c_offset);
1619 dga_win_bbox(win, &x, &y, &w, &h);
1620 if (((curgp->c_org.x + curg_mpr->curg_dim.x) < x) ||
1621 (curgp->c_org.x > (x + w)) ||
1622 ((curgp->c_org.y + curg_mpr->curg_dim.y) < y) ||
1623 (curgp->c_org.y > (y + h)))
1624 return;
1626 if (func) {
1627 curg_mem.width = curg_mpr->curg_dim.x;
1628 curg_mem.height = curg_mpr->curg_dim.y;
1629 curg_mem.depth = curg_mpr->curg_depth;
1630 curg_mem.linebytes = curg_mpr->curg_linebytes;
1631 #ifdef _LP64
1632 curg_mem.memptr = (void *)(curg_mpr + 1);
1633 #else /* _LP64 */
1634 curg_mem.memptr = ((caddr_t) curg_mpr) + sizeof(Dga_curs_mpr);
1635 #endif /* _LP64 */
1636 (*func) (data, win, curgp->c_org.x, curgp->c_org.y, &curg_mem);
1637 curgp->c_state_flag = DGA_CURSOR_DOWN;
1638 /* have to bump the shared memory counter, so update the saved
1639 * version as well
1641 win->c_curseq = ++(curgp->c_chng_cnt);
1645 Dga_dbinfo *
1646 dga_win_dbinfop(wini)
1647 Dga_window wini;
1649 _Dga_window win = (struct dga_window *)wini;
1650 return ((Dga_dbinfo *)&(((WXINFO *) win->w_info)->wx_dbuf));
1653 Dga_widinfo *
1654 dga_win_widinfop(wini)
1655 Dga_window wini;
1657 _Dga_window win = (struct dga_window *)wini;
1658 return ((Dga_widinfo *)(&(((WXINFO *) win->w_info)->w_wid_info)));
1661 void
1662 dga_win_set_client_infop(wini, client_info_ptr)
1663 Dga_window wini;
1664 void* client_info_ptr;
1666 _Dga_window win = (struct dga_window *)wini;
1667 win->w_client = client_info_ptr;
1670 void *
1671 dga_win_get_client_infop(wini)
1672 Dga_window wini;
1674 _Dga_window win = (struct dga_window *)wini;
1675 return (void *)(win->w_client);
1679 static int
1680 dgai_win_initMbufset (_Dga_window dgawin)
1682 WXINFO *infop;
1683 int status = 0;
1685 /* Lock the window to see if it is multibuffered */
1686 #ifndef SERVER_DGA
1687 DGA_LOCK(dgawin);
1688 #endif /* SERVER_DGA */
1690 infop = (WXINFO *) dgawin->w_info;
1691 if (!infop->w_mbsInfo.enabled) {
1692 /* it's okay if it's not multibuffered; return success */
1693 dgawin->pMbs = NULL;
1694 status = 1;
1695 goto Exit;
1698 if (!(dgawin->pMbs = dgai_mbufset_create(dgawin))) {
1699 goto Exit;
1702 dgawin->c_mbcomposseq = *dgawin->s_mbcomposseq_p;
1704 /* success */
1705 status = 1;
1707 Exit:
1708 #ifndef SERVER_DGA
1709 DGA_UNLOCK(dgawin);
1710 #endif /* SERVER_DGA */
1711 return (status);
1714 #ifdef SERVER_DGA
1716 * There is no equivalent for the following function in client side
1717 * The main purpose of this function is to isolate SHAPES header files
1718 * and XGL files.
1721 void
1722 dga_win_lock(win)
1723 Dga_window win;
1725 _Dga_window wini = (_Dga_window)win;
1727 if (((wini)->w_lockcnt)++ == 0) {
1728 wg_lock((WXINFO *) (wini->w_lib_private));
1729 DGA_S_LOCK(wini);
1730 wini->w_modif = ((((wini)->c_chngcnt) == (*((wini)->s_chngcnt_p)))
1731 ? 0 : (*((wini)->w_update_func))(wini));
1737 * There is no equivalent for the following function in client side
1738 * The main purpose of this function is to isolate SHAPES header file
1739 * and XGL files.
1742 void
1743 dga_win_unlock(win)
1744 Dga_window win;
1746 _Dga_window wini = (_Dga_window)win;
1748 if (--((wini)->w_lockcnt) == 0) {
1749 wg_unlock((WXINFO *) (wini->w_lib_private));
1750 if ((wini)->w_unlock_func)
1751 (*((wini)->w_unlock_func))(wini);
1755 #endif /* SERVER_DGA */
1758 #ifdef DEBUG
1759 dga_win_dump(clientpi)
1760 Dga_window clientpi ;
1762 _Dga_window clientp = (struct dga_window *)clientpi;
1763 WXINFO *infop = (WXINFO *) clientp->w_info ;
1765 printf("client page is %p\n", clientp) ;
1766 printf(" w_info = %p\n", (WXINFO *) clientp->w_info) ;
1767 printf(" w_next = %p\n", clientp->w_next) ;
1768 printf(" w_client = %p\n", clientp->w_client) ;
1769 printf(" c_clipseq = %u\n", clientp->c_clipseq) ;
1770 printf(" s_clipseq_p = %p\n", clientp->s_clipseq_p) ;
1771 printf(" w_update_func = %p\n", clientp->w_update_func) ;
1772 printf(" w_infofd = %d\n", clientp->w_infofd) ;
1773 printf(" w_devfd = %d\n", clientp->w_devfd) ;
1774 printf(" w_lockcnt = %d\n", clientp->w_lockcnt) ;
1775 printf(" w_lockp = %p\n", clientp->w_lockp) ;
1776 printf(" w_unlockp = %p\n", clientp->w_unlockp) ;
1777 printf(" w_clipptr = %p\n", clientp->w_clipptr) ;
1778 printf(" w_cliplen = %u\n", clientp->w_cliplen) ;
1780 printf("info page is %p\n", infop) ;
1781 printf(" w_flag = %lu\n", infop->w_flag) ;
1782 printf(" w_magic = %ld\n", infop->w_magic) ;
1783 printf(" w_version = %ld\n", infop->w_version) ;
1784 printf(" w_cunlockp = %p\n", infop->w_cunlockp) ;
1785 printf(" w_devname = %s\n", infop->w_devname) ;
1786 printf(" w_cookie = %lu\n", infop->w_cookie) ;
1787 printf(" w_clipoff = %ld\n", infop->u.vn.w_clipoff) ;
1788 printf(" w_scliplen = %u\n", infop->w_scliplen) ;
1789 printf(" w_org = %u,(%f,%f)\n",
1790 infop->w_org.t, infop->w_org.x/65536., infop->w_org.y/65536.) ;
1791 printf(" w_dim = %u,(%f,%f)\n",
1792 infop->w_dim.t, infop->w_dim.x/65536., infop->w_dim.y/65536.) ;
1793 printf(" &w_shape_hdr = %p\n", &infop->u.v0.w_shape_hdr) ;
1794 printf(" &w_shape = %p\n", &infop->w_shape) ;
1795 printf(" w_shape.SHAPE_FLAGS = %u\n", infop->w_shape.SHAPE_FLAGS) ;
1796 printf(" w_shape.SHAPE_YMIN = %d\n", infop->w_shape.SHAPE_YMIN) ;
1797 printf(" w_shape.SHAPE_YMAX = %d\n", infop->w_shape.SHAPE_YMAX) ;
1798 printf(" w_shape.SHAPE_XMIN = %d\n", infop->w_shape.SHAPE_XMIN) ;
1799 printf(" w_shape.SHAPE_XMAX = %d\n", infop->w_shape.SHAPE_XMAX) ;
1800 printf(" w_shape.SHAPE_X_EOL = %d\n", infop->w_shape.SHAPE_X_EOL) ;
1801 printf(" w_shape.SHAPE_Y_EOL = %d\n", infop->w_shape.u.SHAPE_Y_EOL) ;
1802 printf(" &w_cliparray = %p\n", &infop->w_cliparray) ;
1804 #endif /* DEBUG */
1806 #ifdef MT
1808 dgai_unlock(Dga_drawable dgadraw)
1810 _Dga_window dgawin;
1812 if (dgaMTOn) {
1813 dgawin = (_Dga_window) dgadraw;
1814 mutex_unlock(dgawin->mutexp);
1816 return Success;
1818 #endif