*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* win_grab.c - the client side code for DGA window grabber
*/
/****
*
*
* Shared window synchronization routines - client side
*
*
*
* Functions:
*
* Dga_window
* dga_win_grab(devfd, token)
* int devfd ;
* Dga_token token ;
*
* Grab a window. 'token' is the window-info handle returned by
* XDgaGrabWindow. 'devfd' is the file descriptor of the frame buffer
* if known, -1 otherwise. If you specify -1, dga_win_grab will open the
* frame buffer. The frame buffer fd may be inquired from the returned
* Dga_window structure via the dga_win_devfd() routine.
*
* Returns a pointer to the a struct dga_window on success, NULL on
* failure.
*
*
*
* dga_win_ungrab(infop, cflag)
* Dga_window infop ;
* int cflag ;
*
* Ungrab a window. All resources allocated by dga_win_grab are freed.
* If 'cflag' is nonzero, the framebuffer fd described for the device
* is also closed.
*
* The application should call XDgaUnGrabWindow(dpy,win) after
* calling dga_win_ungrab() so that the server may free the window-info
* page at the other end.
*
*
*
* short *
* dga_win_clipinfo(win)
* Dga_window win ;
*
* Returns pointer to cliplist. Replaces old wx_sh_clipinfo_c() macro.
*
*
*
* char *
* dga_win_fbname(win)
* Dga_window win ;
*
* Returns name of fb. Replaces old wx_devname_c() macro.
*
*
*
* int
* dga_win_clipchg(win)
* Dga_window win ;
*
* Returns 1 if cliplist changed since last call. Replaces old
* wx_modif_c() and wx_seen_c() macros.
*
*
*
* int
* dga_win_curschg(win)
* Dga_window win ;
*
* Returns 1 if cursor changed since last call.
*
*
*
* int
* dga_win_rtnchg(win)
* Dga_window win ;
*
* Returns 1 if retained info changed since last call.
*
*
*
* int
* dga_win_devfd(win)
* Dga_window win ;
*
* Returns framebuffer fd.
*
*
*
* dga_win_bbox(win, xp, yp, widthp, heightp)
* Dga_window win;
* int *xp, *yp, *widthp, *heightp;
*
* Returns window bounding box
*
*
*
* int
* dga_win_singlerect(win)
* Dga_window win;
*
* Returns nonzero if the window is a single rectangle.
*
*
*
* int
* dga_win_empty(win)
* Dga_window win;
*
* Returns nonzero if the window is empty.
*
*
*
* int
* dga_win_obscured(win)
* Dga_window win;
*
* Returns nonzero if the window is obscured.
*
*
*
* int
* dga_win_cursactive(win)
* Dga_window win;
*
* Returns nonzero if the cursor grabber is active.
*
*
*
* void
* dga_win_cursupdate(win, func, data)
* Dga_window win;
* void (*func)();
* void* data;
*
* Decide if the cursor needs to be taken down, and if so, call
* (*func)(data, win, x, y, mem)
* void* data ;
* Dga_window win ;
* int x,y ;
* Dga_curs_mpr *mem ;
*
*
*
* Dga_dbinfo *
* dga_win_dbinfop(win)
* Dga_window win;
*
* Return dbinfo pointer.
*
*
*
* Dga_widinfo *
* dga_win_widinfop(win)
* Dga_window win;
*
* Return window id info pointer.
*
* dga_win_depth(win)
* Dga_window win;
*
* Return windows depth .
*
*
* dga_win_borderwidth(win)
* Dga_window win;
*
* Return windows borderwidth .
*
* void
* dga_win_set_client_infop(win, client_info_ptr)
* Dga_window win;
* void* client_info_ptr;
* Sets a client specific pointer in Dga_window
*
*
* dga_win_get_client_infop(win)
* Dga_window win;
* Returns the client specific pointer
*
****/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef SERVER_DGA
#include "windowstr.h"
#include "dga_externaldefs.h"
#include "dga/dgawinstr.h"
#else
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#ifdef SVR4
#else
#include <fcntl.h>
#endif
#endif /* SERVER_DGA */
#include "dga_incls.h"
#include "rtn_grab.h"
#if 0
#ifdef DEBUG
extern int sys_nerr;
extern char *sys_errlist[] ;
#endif
#endif
/* Some structure definition for internal bookkeeping */
typedef struct dga_winlist {
* using drawable i/f. */
#ifdef MT
#endif
} *Dga_winlist;
/*bug fix for 4248958: use safe_free_client() to replace free() */
void
{
if(clientp){
}
}
/******************************************
*
* dgai_win_grab_common:
*
* create shared memory file for window information
* map to lock page
*
* arguments:
*
* int devfd; INPUT
* file descriptor of graphics device
*
* Dga_token token; INPUT
* magic cookie supplied by the server
*
* returns a user virtual address for a dga_window structure.
* returns NULL if anything goes awry.
*
* 'devfd' is the file descriptor of the frame buffer, if known,
* -1 otherwise. If you specify -1, wx_grab will open the
* frame buffer. The frame buffer fd may be inquired from the returned
* Dga_window ptr to the struct dga_window via the dga_win_devfd() routine.
*
*****************************************/
/*
** Shared between both drawable grabber and window compatibility interface.
*/
{
int lockfd ;
int filefd;
int locktype ;
int i;
#ifdef SERVER_DGA
return NULL;
}
#endif /* SERVER_DGA */
/* First, check if already grabbed by this client. Note that we
always treat the new drawable and old window grabbers separately */
/* If multiple clients are grabbing the same
* window, then we duplicate the per client info
* structure and return that instead of the original
* allocated clientp structure. Also remember to add
* this new info structure to the linked list. This
* change obsoletes the w_grab_count field which
* will always be equal to 1
*/
if ((new_clientp =
return NULL ;
if (drawableGrabber) {
if (wlist->dga_clientplist_draw)
else
*new_clientp = *orig_clientp;
new_clientp->w_lockcnt =0;
if (wlist->dga_clientplist_draw) {
/* Add it to the list of clientp structure associated
* with this window */
} else {
/* Need to initialize all drawableGrabber
* specific data. */
/* mismatch on 64 bit port or other trouble */
"wx_grab: mismatch on shared WXINFO size info page is %d sizeof is %d \n",
return(NULL);
}
(int(*)())dgai_mbsmemb_update;
new_clientp->c_mbufseq = 0;
new_clientp->c_mbcomposseq = 0;
new_clientp->c_devinfoseq = 0;
new_clientp->changeMask = 0;
new_clientp->prevWasMbuffered = 0;
new_clientp->prevLocked = 0;
if (!dgai_win_initMbufset(new_clientp)) {
}
}
}
/* the same mbufset is shared between all client
* structures for this window */
if (orig_clientp->pMbs) {
}
#ifdef MT
/* Same window was grabbed 2 or more times via the
* drawable interface so turn per-drawable MT
* locking on if we are linked with -lthread also.
*/
if (dgaThreaded) {
/* Currently, this variable gets set to 1 and
* never gets turned off. This could be optimized
* if needed.
*/
dgaMTOn = 1;
}
#endif
return new_clientp;
} else {
if (wlist->dga_clientplist)
else
*new_clientp = *orig_clientp;
new_clientp->w_lockcnt =0;
if (wlist->dga_clientplist) {
/* Add it to the list of clientp structure associated
* with this window */
} else {
}
#ifdef MT
#endif
return new_clientp;
}
}
}
if( (clientp =
return NULL ;
#ifdef SERVER_DGA
{
/* Now get a pointer to the shared info page from
* pWin's private data */
}
#else
return((Dga_window)NULL);
}
/* map the wx_winfo area */
(off_t)0);
return((Dga_window)NULL);
}
/* mismatch on 64 bit port or other trouble */
#ifdef DEBUG
"wx_grab: mismatch on WXINFO size info page is %d sizeof is %d \n",
#endif
return(NULL);
}
/* open the frame buffer if not already opened by client */
if( devfd >= 0 )
else {
if( lockfd < 0 ) {
#ifdef DEBUG
#endif
return NULL ;
}
}
#endif /* SERVER_DGA */
if (drawableGrabber) {
}
#ifdef SERVER_DGA
#else
/* On cursor-grabbed devices, find out if we already have a
* lockp, unlockp, and cursor page mapping for this device.
* We don't want to grab the same lockpage, etc. twice.
*/
if (winp) {
}
}
/* only get new lock pages if necessary */
switch( locktype ) {
case WG_LOCKDEV:
/* map the lock page */
#ifdef DEBUG
#endif
if( devfd < 0 )
return(NULL);
}
/* map the unlock page */
#ifdef DEBUG
#endif
if( devfd < 0 )
return(NULL);
}
break ;
case WG_WINLOCK:
if( devfd < 0 )
return(NULL);
}
break ;
}
}
/* cursor grabber stuff */
int curs_fd;
/* open the shared cursor page */
#ifdef DEBUG
#endif
return((Dga_window)NULL);
}
/* Map it */
(off_t)0);
#ifdef DEBUG
#endif
return(NULL);
}
/* check to see if you have a good magic number */
#ifdef DEBUG
#endif
return(NULL);
}
}
#endif /* SERVER_DGA */
/* success, fill out rest of structure */
if (drawableGrabber) {
} else {
/* compatibility */
}
#ifdef MT
if (dgaThreaded) {
} else {
}
#else
#endif
}
} else {
for (i = 0; i < DGA_MAX_GRABBABLE_BUFS + 1; i ++) {
clientp->c_wm_chngcnt[i] = 0;
#ifdef MT
clientp->shadow_chngcnt[i] = 0;
#endif
}
}
/* Now initialize the next field to pt to the second member of
* c_wm_chngcnt array - this is specifically for performance
* tuning of the lock macro
*/
} else {
/* so first test of dga_win_curschg will see a change */
}
return NULL;
return NULL;
return NULL;
return NULL;
return NULL;
clientp->buf_resize_flag = 0;
clientp->c_buffer_swap = 0;
clientp->db_enabled = 0;
/* initialization for drawable grabber code */
if (drawableGrabber) {
clientp->c_mbcomposseq = 0;
clientp->c_devinfoseq = 0;
clientp->changeMask = 0;
clientp->prevWasMbuffered = 0;
clientp->prevLocked = 0;
}
/* add to linked list of grabbed windows - for internal bookkeeping
* Note: this should be done last in order for other code, e.g.
* check_other_curg_windows() to work correctly
*/
if (!dga_wlist) {
if ((dga_wlist =
return NULL ;
if (drawableGrabber) {
} else {
}
} else {
if ((new_wlist =
return NULL;
if (drawableGrabber) {
} else {
}
}
#ifndef SERVER_DGA
#endif /* SERVER_DGA */
#ifdef MT
#endif
/* If window is multibuffered, initialize multibuffer set */
/* If window is being grabbed through the old interface don't
* init the mbufset since mbuffers where not supported int
* older versions of DGA */
if (!dgai_win_initMbufset(clientp)) {
dga_win_ungrab(clientp, 0);
}
}
return((Dga_window)clientp);
}
int devfd;
{
/* Call the common grab routine with dpy == NULL to signify that
* mbuffers are not to be initialized. */
}
#ifndef SERVER_DGA
static _Dga_window
{
return(clientp);
}
}
return(clientp);
}
}
}
return NULL;
}
static void
int devfd ;
{
int locktype ;
/* don't free lock pages
* Note: check both clientp->curs_info and infop->c_sinfo because
* this routine is called both at grab and ungrab time. Client
* may not have set curs_info non-zero at grab time. Server may
* set c_sinfo NULL at window destroy time.
*/
} else {
switch(locktype ) {
case WG_LOCKDEV:
break ;
case WG_WINLOCK:
break ;
}
}
if( devfd < 0 )
}
#endif /* SERVER_DGA */
void
int cflag ;
{
}
void
int cflag ;
int drawableGrabber;
{
/* remove from linked list of grabbed windows
* Note: this should be done first in order for other code, e.g.
* check_other_curg_windows() to work correctly
*/
match = 0;
while (winp) {
if (drawableGrabber)
else
while (clntp) {
match = 1;
if( prevclntp )
else {
if (drawableGrabber)
else
}
break;
}
}
if (!match) {
/* Check for old style clients */
while (clntp) {
match = 1;
if( prevclntp )
else {
if (drawableGrabber)
else
}
break;
}
}
}
break ;
}
}
if (!match)
return; /* error */
/* TODO: do this for every client, or only once? */
#ifndef SERVER_DGA
/* Cursor grabber stuff */
/* TODO: do this for every client, or only once? */
}
#endif /* SERVER_DGA */
/* deref any associated multibuffer set */
}
/* TODO: shouldn't we free the clientp??? */
/* Now check to see if all that needs to be freed has been freed */
#ifndef SERVER_DGA
#endif /* SERVER_DGA */
/* Then free this node and unlink it from the list */
else
#ifdef MT
#endif
}
}
int
{
int match;
/* Checking to see if this client is grabbing a multiply grabbed
* window
*/
match = 0;
while (winp) {
/* Now we have the correct window */
if (drawableGrabber)
else
while (clntp) {
/* Now we have the correct client */
/* Check to see if there are any more... */
match = 1;
break;
}
}
}
if (match) break;
}
}
return match;
}
short *
{
return((short *)&((struct class_SHAPE_vn *)((char *)(infop) +
}
char *
{
}
int
{
return 1;
}
return 0;
}
int
{
return 1;
}
return 0;
}
int
{
/* rtn grabbed, but not currently mapped */
/* just went unmapped */
return 1;
}
return 0;
}
/* otherwise either not rtn grabbed or have a rtn mapping */
return 1;
}
return 0;
}
int
{
}
void
{
return;
}
}
int
{
}
int
{
}
{
else
return 0;
}
{
return(infop->w_borderwidth);
else
return 0;
}
int
{
int tmp;
short *ptr;
}
}
return 1;
}
}
return 0;
}
int
{
if (dga_win_empty(wini))
return (DGA_VIS_FULLY_OBSCURED);
/* This routine returns the reverse of what one would think.
* it returns true if the window is unobscured false otherwise. */
else if (!dga_win_obscured(wini))
return (DGA_VIS_PARTIALLY_OBSCURED);
return (DGA_VIS_UNOBSCURED);
/* This will work when we get to R6 but for now the visibility
* entry in the window structure (which is where this comes from)
* is bogus. I looked at the R6 code and it looks like they
* attempted to get this working.
_Dga_window win = (struct dga_window *)wini;
WXINFO *infop = (WXINFO *) win->w_info;
return (infop->w_visibility);
*/
}
void
{
* it takes so long.
*/
unsigned int cliplen;
short *clipptr;
short *cmclip;
#ifndef SERVER_DGA
int filefd;
#endif /*SERVER_DGA */
#ifdef SERVER_DGA
}
} else {
}
}
#else
while(1) {
/* server has an extended mapping */
/* ...and we don't. */
return;
}
return;
}
if ((int)clipptr != -1) {
}
continue; /* at while */
}
/* ...and we do... but the wrong size. */
return;
}
return;
}
if ((int)clipptr == -1)
else {
}
continue; /* at while */
}
} else {
/* server doesn't have an extended mapping */
/* ...and we do. */
return;
}
return;
}
continue; /* at while */
}
/*
else { ...nor do we
break;
}
*/
}
break;
}
#endif /* SERVER_DGA */
}
void
{
* it takes so long.
*
* We can add code here in the future to remap the cursor page,
* etc., if we want.
*/
return;
}
/*
*
* dgai_rtn_update()
*
* it takes so long. Remap retained info, etc.
*
* DGA Retained Window Information Update. This function checks that the
* shared retained information structure hasn't become obsolete. If the
* structure is found to be obsolete, this routine attempts to free and
* re-allocate the resources associated with the retained window. Nothing
* is done in the event that the shared retained information is not obsolete.
*
* Inputs: Dga_window - Pointer to the dga_window structure for which
* the the shared retained info structure is to
* be removed.
*
* Outputs: None.
*
* Globals: None.
*
* Externals: DGA_LOCK() DGA MACRO
* DGA_UNLOCK() DGA MACRO
* RTN_INFOP() DGA MACRO
* _dga_rtn_map()
* _dga_rtn_unmap()
*
*/
void
{
unsigned int mapped;
#ifdef SERVER_DGA
/* mapped, but obsolete */
(void) _dga_rtn_unmap(clientp);
(void) _dga_rtn_map(clientp);
}
/* unmapped on client side, but server has valid w_srtndlink */
(void) _dga_rtn_map(clientp);
}
#else
while (1) {
/* mapped, but obsolete */
(void) _dga_rtn_unmap(clientp);
(void) _dga_rtn_map(clientp);
continue;
}
/* unmapped on client side, but server has valid w_srtndlink */
(void) _dga_rtn_map(clientp);
continue;
}
break;
}
#endif /* SERVER_DGA */
}
static int
{
/* establish the new real lock subject */
/* save last lock subject. This may be used later in the update phase */
/* start out assuming we're not aliased. This may change if we detect
aliasing later in the update phase */
* it takes so long. Also, update win->c_chngcnt.
*/
do {
/* repeat update functions as needed
*/
}
}
}
/* pre OWV3 */
return 1;
} else {
/* post OWV3 beta */
return 1;
}
}
int
{
return 1;
return 0;
}
void
void (*func)();
void* data;
{
/* assumes the window is already locked */
int x, y, w, h;
return;
dga_win_bbox(win, &x, &y, &w, &h);
return;
if (func) {
#ifdef _LP64
#else /* _LP64 */
#endif /* _LP64 */
/* have to bump the shared memory counter, so update the saved
* version as well
*/
}
}
{
}
{
}
void
void* client_info_ptr;
{
}
void *
{
}
static int
{
int status = 0;
/* Lock the window to see if it is multibuffered */
#ifndef SERVER_DGA
#endif /* SERVER_DGA */
/* it's okay if it's not multibuffered; return success */
status = 1;
goto Exit;
}
goto Exit;
}
/* success */
status = 1;
Exit:
#ifndef SERVER_DGA
#endif /* SERVER_DGA */
return (status);
}
#ifdef SERVER_DGA
/*
* There is no equivalent for the following function in client side
* The main purpose of this function is to isolate SHAPES header files
* and XGL files.
*/
void
{
}
}
/*
* There is no equivalent for the following function in client side
* The main purpose of this function is to isolate SHAPES header file
* and XGL files.
*/
void
{
if ((wini)->w_unlock_func)
}
}
#endif /* SERVER_DGA */
#ifdef DEBUG
{
printf(" w_org = %u,(%f,%f)\n",
printf(" w_dim = %u,(%f,%f)\n",
}
#endif /* DEBUG */
#ifdef MT
int
{
if (dgaMTOn) {
}
}
#endif