summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2003-04-25 11:22:34 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2003-04-25 11:22:34 +0000
commit29eac4de82f52c8b76842616a0cfea52c7037062 (patch)
tree434e935d6b877ead35c1f1c30e1fa3429f173f63
parentee4b2f22b816008ab80300fa32a4f56600d04e34 (diff)
get client & server processes working properly
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.c47
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.h15
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_subset_select.c114
-rw-r--r--src/mesa/drivers/dri/radeon/server/radeon_dri.c143
-rw-r--r--src/miniglx/dri_util.c24
-rw-r--r--src/miniglx/miniglx.c69
-rw-r--r--src/miniglx/miniglxP.h33
-rw-r--r--src/miniglx/miniglx_events.c329
8 files changed, 436 insertions, 338 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c
index 5bc74836a5..f0ef672931 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.c
@@ -134,6 +134,12 @@ static void validate_drawable( radeonContextPtr rmesa )
fprintf(stderr, "%s\n", __FUNCTION__);
+ fprintf(stderr,
+ "rmesa->lastStamp %d dpriv->lastStamp %d *(dpriv->pStamp) %d\n",
+ rmesa->lastStamp,
+ dPriv->lastStamp,
+ *(dPriv->pStamp));
+
/* The window might have moved, so we might need to get new clip
* rects.
*
@@ -144,7 +150,8 @@ static void validate_drawable( radeonContextPtr rmesa )
*/
DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
- if ( rmesa->lastStamp != dPriv->lastStamp ) {
+ if ( rmesa->lastStamp == 0 ||
+ rmesa->lastStamp != dPriv->lastStamp ) {
radeonUpdatePageFlipping( rmesa );
if (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT)
@@ -171,21 +178,9 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
int i;
- while (1) {
- drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags );
-
- validate_drawable( rmesa );
-
- fprintf(stderr, "%s %d\n", __FUNCTION__, rmesa->numClipRects);
-
- if (rmesa->numClipRects)
- break;
-
- drmUnlock( rmesa->dri.fd, rmesa->dri.hwContext );
-
- sleep(10);
- }
-
+ drmGetLock( rmesa->dri.fd, rmesa->dri.hwContext, flags );
+
+ validate_drawable( rmesa );
if ( sarea->ctxOwner != rmesa->dri.hwContext ) {
sarea->ctxOwner = rmesa->dri.hwContext;
@@ -200,23 +195,3 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
}
-extern void __miniglx_release_vt( void );
-
-/* In the current miniglx, cliprects can change while the lock is
- * held... Probably need to fix this.
- */
-void radeonUnlock( radeonContextPtr rmesa )
-{
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- drmUnlock( rmesa->dri.fd, rmesa->dri.hwContext );
-
- validate_drawable( rmesa );
-
- /* This only happens if the VT switch was requested inside the
- * locked region.
- */
- if (!rmesa->numClipRects)
- __miniglx_release_vt();
-
-}
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h
index f8e35369ee..61b74eae11 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.h
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.h
@@ -38,7 +38,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define __RADEON_LOCK_H__
extern void radeonGetLock( radeonContextPtr rmesa, GLuint flags );
-extern void radeonUnlock( radeonContextPtr rmesa );
/* Turn DEBUG_LOCKING on to find locking conflicts.
*/
@@ -100,13 +99,13 @@ extern int prevLockLine;
/* Unlock the hardware.
*/
-#define UNLOCK_HARDWARE( rmesa ) \
- do { \
- DRM_CAS_RESULT(__ret); \
- DRM_CAS( rmesa->dri.hwLock,DRM_LOCK_HELD|rmesa->dri.hwContext, \
- rmesa->dri.hwContext,__ret); \
- if (__ret) radeonUnlock( rmesa ); \
- DEBUG_RESET(); \
+#define UNLOCK_HARDWARE( rmesa ) \
+ do { \
+ DRM_UNLOCK( rmesa->dri.fd, \
+ rmesa->dri.hwLock, \
+ rmesa->dri.hwContext ); \
+ DEBUG_RESET(); \
} while (0)
+
#endif /* __RADEON_LOCK_H__ */
diff --git a/src/mesa/drivers/dri/radeon/radeon_subset_select.c b/src/mesa/drivers/dri/radeon/radeon_subset_select.c
index bb491177bf..c1f3535f53 100644
--- a/src/mesa/drivers/dri/radeon/radeon_subset_select.c
+++ b/src/mesa/drivers/dri/radeon/radeon_subset_select.c
@@ -27,7 +27,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/* $Id: radeon_subset_select.c,v 1.1.2.5 2003/03/17 21:23:00 keithw Exp $ */
+/* $Id: radeon_subset_select.c,v 1.1.2.6 2003/04/25 11:22:34 keithw Exp $ */
#include "glheader.h"
@@ -955,6 +955,105 @@ void radeon_select_Install( GLcontext *ctx )
ctx->Driver.FlushVertices = radeonSelectFlushVertices;
}
+/*@}*/
+
+
+/**********************************************************************/
+/** \name Noop mode for operation without focus */
+/**********************************************************************/
+/*@{*/
+
+
+/**
+ * \brief Process glBegin().
+ *
+ * \param mode primitive.
+ */
+static void radeon_noop_Begin(GLenum mode)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
+ if (mode > GL_POLYGON) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" );
+ return;
+ }
+
+ if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
+ _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
+ return;
+ }
+
+ if (rmesa->dri.drawable->numClipRects) {
+ radeonVtxfmtInit( ctx );
+ ctx->Exec->Begin( mode );
+ return;
+ }
+
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ ctx->Driver.CurrentExecPrimitive = mode;
+}
+
+/**
+ * \brief Process glEnd().
+ */
+static void radeon_noop_End(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1;
+}
+
+/**
+ * \brief Discards all arguments.
+ */
+static void radeon_noop_Vertex2f(GLfloat x, GLfloat y)
+{
+}
+
+/**
+ * \brief Discards all arguments.
+ */
+static void radeon_noop_Vertexfv(const GLfloat * v)
+{
+}
+
+/**
+ * \brief Discards all arguments.
+ */
+static void radeon_noop_Vertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+}
+
+/**
+ * \brief Install the noop callbacks.
+ *
+ * \param ctx GL context.
+ *
+ * Installs the noop callbacks into the glapi table. These functions
+ * will not attempt to emit any DMA vertices, but will keep internal
+ * GL state uptodate. Borrows heavily from the select code.
+ */
+static void radeon_noop_Install( GLcontext *ctx )
+{
+ struct _glapi_table *exec = ctx->Exec;
+
+ exec->Color3f = radeon_select_Color3f;
+ exec->Color3fv = radeon_select_Color3fv;
+ exec->Color4f = radeon_select_Color4f;
+ exec->Color4fv = radeon_select_Color4fv;
+ exec->TexCoord2f = radeon_select_TexCoord2f;
+ exec->TexCoord2fv = radeon_select_TexCoord2fv;
+ exec->Vertex2f = radeon_noop_Vertex2f;
+ exec->Vertex2fv = radeon_noop_Vertexfv;
+ exec->Vertex3f = radeon_noop_Vertex3f;
+ exec->Vertex3fv = radeon_noop_Vertexfv;
+ exec->Begin = radeon_noop_Begin;
+ exec->End = radeon_noop_End;
+
+ ctx->Driver.FlushVertices = radeonSelectFlushVertices;
+}
+
+/*@}*/
/**
* \brief Set rasterization mode.
@@ -962,14 +1061,21 @@ void radeon_select_Install( GLcontext *ctx )
* \param ctx GL context.
* \param mode rasterization mode. Supports GL_RENDER or
*
- * Calls either radeonVtxfmtInit() or radeon_select_Install() according \p mode
- * is GL_RENDER or GL_SELECT.
+ * If mode is GL_RENDER, calls either radeonVtxfmtInit() or
+ * radeon_noop_Install depending on whether the application has focus
+ * (ie a fullscreen-cliprect) or not. If mode is GL_SELECT, calls
+ * radeon_select_Install().
*/
static void radeonRenderMode( GLcontext *ctx, GLenum mode )
{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+
switch (mode) {
case GL_RENDER:
- radeonVtxfmtInit( ctx );
+ if (rmesa->dri.drawable->numClipRects)
+ radeonVtxfmtInit( ctx );
+ else
+ radeon_noop_Install( ctx );
break;
case GL_SELECT:
radeon_select_Install( ctx );
diff --git a/src/mesa/drivers/dri/radeon/server/radeon_dri.c b/src/mesa/drivers/dri/radeon/server/radeon_dri.c
index af3193d645..91b7aa4c17 100644
--- a/src/mesa/drivers/dri/radeon/server/radeon_dri.c
+++ b/src/mesa/drivers/dri/radeon/server/radeon_dri.c
@@ -161,17 +161,16 @@ static void RADEONEngineReset( struct MiniGLXDisplayRec *dpy )
* \brief Restore the drawing engine.
*
* \param dpy display handle
- * \param info driver private data.
*
* Resets the graphics card and sets initial values for several registers of
* the card's drawing engine.
+ *
+ * Turns on the radeon command processor engine (ie: the ringbuffer).
*/
-static void RADEONEngineRestore( struct MiniGLXDisplayRec *dpy,
- RADEONInfoPtr info )
-
+static int RADEONEngineRestore( struct MiniGLXDisplayRec *dpy )
{
unsigned char *RADEONMMIO = dpy->MMIOAddress;
- int pitch64, datatype, dp_gui_master_cntl;
+ int pitch64, datatype, dp_gui_master_cntl, err;
OUTREG(RADEON_RB3D_CNTL, 0);
RADEONEngineReset( dpy );
@@ -179,7 +178,7 @@ static void RADEONEngineRestore( struct MiniGLXDisplayRec *dpy,
switch (dpy->bpp) {
case 16: datatype = 4; break;
case 32: datatype = 6; break;
- default: return;
+ default: return 0;
}
dp_gui_master_cntl =
@@ -216,6 +215,43 @@ static void RADEONEngineRestore( struct MiniGLXDisplayRec *dpy,
/* RADEONWaitForIdleMMIO(dpy); */
usleep(100);
+
+
+ /* Initialize and start the CP if required */
+ if ((err = drmCommandNone(dpy->drmFD, DRM_RADEON_CP_START)) != 0) {
+ fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err);
+ return 0;
+ }
+
+ return True;
+}
+
+
+/**
+ * \brief Shutdown the drawing engine.
+ *
+ * \param dpy display handle
+ *
+ * Turns off the command processor engine & restores the graphics card
+ * to a state that fbdev understands.
+ */
+static int RADEONEngineShutdown( struct MiniGLXDisplayRec *dpy )
+{
+ int err;
+
+ /* Idle the CP engine */
+ if ((err = drmCommandNone(dpy->drmFD, DRM_RADEON_CP_IDLE)) != 0) {
+ fprintf(stderr, "%s: CP idle %d\n", __FUNCTION__, err);
+ return 0;
+ }
+
+ /* Stop the CP */
+ if ((err = drmCommandNone(dpy->drmFD, DRM_RADEON_CP_STOP)) != 0) {
+ fprintf(stderr, "%s: CP stop %d\n", __FUNCTION__, err);
+ return 0;
+ }
+
+ return True;
}
/**
@@ -650,36 +686,6 @@ static int RADEONMemoryInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
return 1;
}
-static void print_client_msg( RADEONDRIPtr pRADEONDRI )
-{
- fprintf(stderr, "deviceID 0x%x\n", pRADEONDRI->deviceID);
- fprintf(stderr, "width 0x%x\n", pRADEONDRI->width);
- fprintf(stderr, "height 0x%x\n", pRADEONDRI->height);
- fprintf(stderr, "depth 0x%x\n", pRADEONDRI->depth);
- fprintf(stderr, "bpp 0x%x\n", pRADEONDRI->bpp);
- fprintf(stderr, "IsPCI 0x%x\n", pRADEONDRI->IsPCI);
- fprintf(stderr, "AGPMode 0x%x\n", pRADEONDRI->AGPMode);
- fprintf(stderr, "frontOffset 0x%x\n", pRADEONDRI->frontOffset);
- fprintf(stderr, "frontPitch 0x%x\n", pRADEONDRI->frontPitch);
- fprintf(stderr, "backOffset 0x%x\n", pRADEONDRI->backOffset);
- fprintf(stderr, "backPitch 0x%x\n", pRADEONDRI->backPitch);
- fprintf(stderr, "depthOffset 0x%x\n", pRADEONDRI->depthOffset);
- fprintf(stderr, "depthPitch 0x%x\n", pRADEONDRI->depthPitch);
- fprintf(stderr, "textureOffset 0x%x\n", pRADEONDRI->textureOffset);
- fprintf(stderr, "textureSize 0x%x\n", pRADEONDRI->textureSize);
- fprintf(stderr, "log2TexGran 0x%x\n", pRADEONDRI->log2TexGran);
- fprintf(stderr, "registerHandle 0x%x\n", (unsigned)pRADEONDRI->registerHandle);
- fprintf(stderr, "registerSize 0x%x\n", pRADEONDRI->registerSize);
- fprintf(stderr, "statusHandle 0x%x\n", (unsigned)pRADEONDRI->statusHandle);
- fprintf(stderr, "statusSize 0x%x\n", pRADEONDRI->statusSize);
- fprintf(stderr, "agpTexHandle 0x%x\n", (unsigned)pRADEONDRI->agpTexHandle);
- fprintf(stderr, "agpTexMapSize 0x%x\n", pRADEONDRI->agpTexMapSize);
- fprintf(stderr, "log2AGPTexGran 0x%x\n", pRADEONDRI->log2AGPTexGran);
- fprintf(stderr, "agpTexOffset 0x%x\n", pRADEONDRI->agpTexOffset);
- fprintf(stderr, "sarea_priv_offset 0x%x\n", pRADEONDRI->sarea_priv_offset);
-}
-
-
/**
@@ -703,7 +709,6 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
{
RADEONDRIPtr pRADEONDRI;
int err;
- unsigned int serverContext;
usleep(100);
assert(!dpy->IsClient);
@@ -822,24 +827,24 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
/* Create a 'server' context so we can grab the lock for
* initialization ioctls.
*/
- if ((err = drmCreateContext(dpy->drmFD, &serverContext)) != 0) {
+ if ((err = drmCreateContext(dpy->drmFD, &dpy->serverContext)) != 0) {
fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
return 0;
}
- DRM_LOCK(dpy->drmFD, dpy->pSAREA, serverContext, 0);
+ DRM_LOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext, 0);
/* Initialize the kernel data structures */
if (!RADEONDRIKernelInit(dpy, info)) {
fprintf(stderr, "RADEONDRIKernelInit failed\n");
- DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext);
+ DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext);
return 0;
}
/* Initialize the vertex buffers list */
if (!RADEONDRIBufInit(dpy, info)) {
fprintf(stderr, "RADEONDRIBufInit failed\n");
- DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext);
+ DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext);
return 0;
}
@@ -849,12 +854,9 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
/* Initialize kernel agp memory manager */
RADEONDRIAgpHeapInit(dpy, info);
- RADEONEngineRestore( dpy, info );
-
- /* Initialize and start the CP if required */
- if ((err = drmCommandNone(dpy->drmFD, DRM_RADEON_CP_START)) != 0) {
- fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err);
- DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext);
+ fprintf(stderr, "calling RADEONEngineRestore from %s\n", __FUNCTION__);
+ if (!RADEONEngineRestore( dpy )) {
+ DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext);
return 0;
}
@@ -882,7 +884,7 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
/* Can release the lock now */
- DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, serverContext);
+ DRM_UNLOCK(dpy->drmFD, dpy->pSAREA, dpy->serverContext);
/* This is the struct passed to radeon_dri.so for its initialization */
dpy->driverClientMsg = malloc(sizeof(RADEONDRIRec));
@@ -914,8 +916,6 @@ static int RADEONScreenInit( struct MiniGLXDisplayRec *dpy, RADEONInfoPtr info )
pRADEONDRI->agpTexOffset = info->agpTexStart;
pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
- print_client_msg( pRADEONDRI );
-
return 1;
}
@@ -1202,46 +1202,6 @@ static void radeonHaltFBDev( struct MiniGLXDisplayRec *dpy )
}
-/**
- * \brief A VT release or aquire signal has been received, and
- * requires some action. We deal with loosing the VT by setting the
- * cliprects to zero and emitting an event to the application.
- */
-static int radeonVTSwitchHandler( struct MiniGLXDisplayRec *dpy, int have_vt )
-{
- int *lock = (int *)dpy->pSAREA;
- int old, new;
- DRM_CAS_RESULT(ret);
- GLXDrawable draw;
- __DRIdrawable *pdraw;
- __DRIdrawablePrivate *pdp;
-
- /* Indicate cliprects have changed
- */
- draw = dpy->TheWindow;
- if (!draw) return 1;
- pdraw = &draw->driDrawable;
- if (!pdraw) return 1;
- pdp = (__DRIdrawablePrivate *) pdraw->private;
- if (!pdp) return 1;
- pdp->lastStamp++;
- pdp->numClipRects = have_vt ? 1 : 0;
-
- /* Mark the lock contended.
- */
- if (!dpy->pSAREA) return 0;
- do {
- old = *(int *)dpy->pSAREA;
- new = old | _DRM_LOCK_CONT;
- DRM_CAS( lock, old, new, ret );
- fprintf(stderr, "old %x new %x\n", old, new );
- } while (ret);
-
- if (have_vt)
- return !(old & _DRM_LOCK_HELD);
- else
- return 1;
-}
/**
* \brief Exported driver interface for Mini GLX.
@@ -1254,5 +1214,6 @@ struct MiniGLXDriverRec __driMiniGLXDriver = {
radeonPostValidateMode,
radeonInitFBDev,
radeonHaltFBDev,
- radeonVTSwitchHandler
+ RADEONEngineShutdown,
+ RADEONEngineRestore
};
diff --git a/src/miniglx/dri_util.c b/src/miniglx/dri_util.c
index 994f16b177..2a3c2000ce 100644
--- a/src/miniglx/dri_util.c
+++ b/src/miniglx/dri_util.c
@@ -22,6 +22,8 @@
#include <linux/fb.h>
#include "GL/miniglx.h"
#include "miniglxP.h"
+#include <linux/vt.h>
+#include <sys/ioctl.h>
#include "sarea.h"
@@ -282,8 +284,12 @@ static Bool driBindContext(Display *dpy, int scrn,
*/
void __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
{
- fprintf(stderr, "%s\n", __FUNCTION__);
- /* nothing to do */
+ __DRIscreenPrivate *psp = pdp->driScreenPriv;
+
+ pdp->numClipRects = psp->pSAREA->drawableTable[pdp->index].flags ? 1 : 0;
+ pdp->lastStamp = *(pdp->pStamp);
+
+ fprintf(stderr, "%s: %d cliprects\n", __FUNCTION__, pdp->numClipRects);
}
@@ -362,11 +368,10 @@ static void *driCreateDrawable(Display *dpy, int scrn,
return NULL;
}
+ pdp->index = dpy->clientID;
pdp->draw = draw;
pdp->refcount = 0;
- pdp->pStamp = &pdp->lastStamp;
- pdp->lastStamp = 1;
- pdp->index = 0;
+ pdp->lastStamp = -1;
pdp->numBackClipRects = 0;
pdp->pBackClipRects = NULL;
pdp->display = dpy;
@@ -411,6 +416,12 @@ static void *driCreateDrawable(Display *dpy, int scrn,
pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */
pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
+ fprintf(stderr, "%s index: %d stamp: %d\n",
+ __FUNCTION__, pdp->index,
+ psp->pSAREA->drawableTable[pdp->index].stamp);
+
+ pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
+ __driUtilUpdateDrawableInfo( pdp );
return (void *) pdp;
}
@@ -790,4 +801,7 @@ __driUtilInitScreen( Display *dpy, int scrn, __DRIscreen *psc )
psc->getDrawable = driGetDrawable;
}
+
+
+
/*@}*/
diff --git a/src/miniglx/miniglx.c b/src/miniglx/miniglx.c
index 2b095f4140..a03978e81d 100644
--- a/src/miniglx/miniglx.c
+++ b/src/miniglx/miniglx.c
@@ -22,7 +22,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/* $Id: miniglx.c,v 1.1.4.51 2003/04/17 15:46:42 keithw Exp $ */
+/* $Id: miniglx.c,v 1.1.4.52 2003/04/25 11:22:36 keithw Exp $ */
/**
@@ -127,73 +127,26 @@ static GLXContext CurrentContext = NULL;
-/* Called from signal handler context, runs atomically wrt
- * XCheckWindowEvent.
- */
-static void queue_event( Display *dpy, int aquire )
-{
- dpy->haveVT = aquire;
- dpy->aquireVTCount += aquire;
- dpy->releaseVTCount += !aquire;
-}
-
static Display *SignalDisplay = 0;
static void SwitchVT(int sig)
{
fprintf(stderr, "SwitchVT %d dpy %p\n", sig, SignalDisplay);
- if (!SignalDisplay) {
- fprintf(stderr, "No display!\n");
- return;
- }
-
- switch( sig )
- {
- case SIGUSR1: /* vt has been released */
- if (SignalDisplay->driver &&
- !SignalDisplay->driver->handleVTSwitch( SignalDisplay, 0 ))
- return;
- if (!SignalDisplay->haveVT) {
- fprintf(stderr, "%s: Don't have VT\n", __FUNCTION__);
- return;
- }
- __miniglx_release_vt();
- break;
- case SIGUSR2: /* vt has been acquired */
- ioctl( SignalDisplay->ConsoleFD, VT_RELDISP, VT_ACTIVATE );
- sleep(1);
-
- if (SignalDisplay->driver &&
- !SignalDisplay->driver->handleVTSwitch( SignalDisplay, 1 ))
- return;
-
- if (SignalDisplay->haveVT) {
- fprintf(stderr, "%s: Already have VT\n", __FUNCTION__);
- return;
+ if (SignalDisplay) {
+ SignalDisplay->vtSignalFlag = 1;
+ switch( sig )
+ {
+ case SIGUSR1: /* vt has been released */
+ SignalDisplay->haveVT = 0;
+ break;
+ case SIGUSR2: /* vt has been acquired */
+ SignalDisplay->haveVT = 1;
+ break;
}
-
- queue_event( SignalDisplay, 1 );
- break;
}
}
-void __miniglx_release_vt( void )
-{
- if (!SignalDisplay)
- return;
-
- if (!SignalDisplay->haveVT) {
- fprintf(stderr, "%s: Don't have VT\n", __FUNCTION__);
- return;
- }
-
- sleep(1);
- ioctl( SignalDisplay->ConsoleFD, VT_RELDISP, 1 );
- queue_event( SignalDisplay, 0 );
-}
-
-
/**********************************************************************/
/** \name Framebuffer device functions */
/**********************************************************************/
diff --git a/src/miniglx/miniglxP.h b/src/miniglx/miniglxP.h
index 052d896fd9..bbee5d6ae4 100644
--- a/src/miniglx/miniglxP.h
+++ b/src/miniglx/miniglxP.h
@@ -206,10 +206,16 @@ struct MiniGLXDriverRec {
*/
void (*haltFBDev)( struct MiniGLXDisplayRec *dpy );
+
/**
- * \brief Handle VT switch events.
+ * \brief Idle and shutdown hardware in preparation for a vt switch.
*/
- int (*handleVTSwitch)( struct MiniGLXDisplayRec *dpy, int have_vt );
+ int (*shutdownHardware)( struct MiniGLXDisplayRec *dpy );
+
+ /**
+ * \brief Restore hardware state after regaining the vt.
+ */
+ int (*restoreHardware)( struct MiniGLXDisplayRec *dpy );
};
@@ -316,22 +322,18 @@ struct MiniGLXDisplayRec {
int ConsoleFD; /**< \brief console TTY device file descriptor */
int FrameBufferFD; /**< \brief framebuffer device file descriptor */
caddr_t FrameBuffer; /**< \brief start of the mmap'd framebuffer */
-/* int FrameBufferSize; */ /**< \brief size of the mmap'd framebuffer in bytes */
caddr_t MMIOAddress; /**< \brief start of the mmap'd MMIO region */
int MMIOSize; /**< \brief size of the mmap'd MMIO region in bytes */
int NumWindows; /**< \brief number of open windows */
Window TheWindow; /**< \brief open window - only allow one window for now */
int rotateMode;
- int haveVT;
- int aquireVTCount;
- int releaseVTCount;
- int exposeNotifyCount;
- int mapNotifyCount;
- int unmapNotifyCount;
+
+ volatile int vtSignalFlag, haveVT;
+ int hwActive;
- int IsClient;
+ int IsClient, clientID;
int nrFds;
struct MiniGLXConnection *fd;
@@ -384,6 +386,13 @@ struct MiniGLXDisplayRec {
/*@}*/
+ /**
+ * \name Client configuration details
+ *
+ * These are computed on the server and sent to clients as part of
+ * the initial handshaking.
+ */
+ /*@{*/
struct {
unsigned long hSAREA;
int SAREASize;
@@ -394,6 +403,7 @@ struct MiniGLXDisplayRec {
int virtualWidth;
int virtualHeight;
} shared;
+ /*@}*/
/**
@@ -401,7 +411,8 @@ struct MiniGLXDisplayRec {
*/
/*@{*/
int drmFD; /**< \brief DRM device file descriptor */
- void *pSAREA;
+ struct _XF86DRISAREA *pSAREA;
+ unsigned int serverContext; /**< \brief DRM context only active on server */
/*@}*/
/**
diff --git a/src/miniglx/miniglx_events.c b/src/miniglx/miniglx_events.c
index 2e2e7d7c5e..6afa9be277 100644
--- a/src/miniglx/miniglx_events.c
+++ b/src/miniglx/miniglx_events.c
@@ -22,7 +22,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-/* $Id: miniglx_events.c,v 1.1.2.3 2003/04/22 14:29:53 keithw Exp $ */
+/* $Id: miniglx_events.c,v 1.1.2.4 2003/04/25 11:22:36 keithw Exp $ */
/**
@@ -62,7 +62,8 @@
#include "miniglxP.h"
-#include "glapi.h"
+#include "xf86drm.h"
+#include "sarea.h"
#define MINIGLX_FIFO_NAME "/tmp/miniglx.fifo"
@@ -95,7 +96,7 @@ static XEvent *queue_event( Display *dpy )
static int dequeue_event( Display *dpy, XEvent *event_return )
{
if (dpy->eventqueue.tail == dpy->eventqueue.head) {
- fprintf(stderr, "dequeue_event: queue empty\n");
+/* fprintf(stderr, "dequeue_event: queue empty\n"); */
return False;
}
else {
@@ -196,6 +197,12 @@ static int welcome_message_part( Display *dpy, int i, void **msg, int sz )
static int welcome_message( Display *dpy, int i )
{
void *tmp = &dpy->shared;
+ int *clientid = dpy->IsClient ? &dpy->clientID : &i;
+
+ if (!welcome_message_part( dpy, i, (void **)&clientid, sizeof(*clientid)))
+ return False;
+
+ fprintf(stderr, "**** CLIENT ID: %d\n", *clientid);
if (!welcome_message_part( dpy, i, &tmp, sizeof(dpy->shared)))
return False;
@@ -261,133 +268,166 @@ static int handle_new_client( Display *dpy )
static int
handle_fifo_read( Display *dpy, int i )
{
- char id = dpy->fd[i].readbuf[0];
- XEvent *er;
- int count = 1;
-
- if (dpy->IsClient) {
- switch (id) {
- /* The server has called 'XMapWindow' on a client window */
- case _YouveGotFocus:
- fprintf(stderr, "_YouveGotFocus\n");
- er = queue_event(dpy);
- if (!er) return False;
- er->xmap.type = MapNotify;
- er->xmap.serial = 0;
- er->xmap.send_event = False;
- er->xmap.display = dpy;
- er->xmap.event = dpy->TheWindow;
- er->xmap.window = dpy->TheWindow;
- er->xmap.override_redirect = False;
- break;
-
- /* The server has called 'XMapWindow' or 'X???' on a client
- * window */
- case _RepaintPlease:
- fprintf(stderr, "_RepaintPlease\n");
- er = queue_event(dpy);
- if (!er) return False;
- er->xexpose.type = Expose;
- er->xexpose.serial = 0;
- er->xexpose.send_event = False;
- er->xexpose.display = dpy;
- er->xexpose.window = dpy->TheWindow;
- if (dpy->rotateMode) {
- er->xexpose.x = dpy->TheWindow->y;
- er->xexpose.y = dpy->TheWindow->x;
- er->xexpose.width = dpy->TheWindow->h;
- er->xexpose.height = dpy->TheWindow->w;
- }
- else {
- er->xexpose.x = dpy->TheWindow->x;
- er->xexpose.y = dpy->TheWindow->y;
- er->xexpose.width = dpy->TheWindow->w;
- er->xexpose.height = dpy->TheWindow->h;
- }
- er->xexpose.count = 0;
- break;
-
- /* The server has called 'XUnmapWindow' on a client window */
- case _YouveLostFocus:
- fprintf(stderr, "_YouveLostFocus\n");
- er = queue_event(dpy);
- if (!er) return False;
- er->xunmap.type = UnmapNotify;
- er->xunmap.serial = 0;
- er->xunmap.send_event = False;
- er->xunmap.display = dpy;
- er->xunmap.event = dpy->TheWindow;
- er->xunmap.window = dpy->TheWindow;
- er->xunmap.from_configure = False;
- break;
+ while (dpy->fd[i].readbuf_count) {
+ char id = dpy->fd[i].readbuf[0];
+ XEvent *er;
+ int count = 1;
+
+ if (dpy->IsClient) {
+ switch (id) {
+ /* The server has called 'XMapWindow' on a client window */
+ case _YouveGotFocus:
+ fprintf(stderr, "_YouveGotFocus\n");
+ er = queue_event(dpy);
+ if (!er) return False;
+ er->xmap.type = MapNotify;
+ er->xmap.serial = 0;
+ er->xmap.send_event = False;
+ er->xmap.display = dpy;
+ er->xmap.event = dpy->TheWindow;
+ er->xmap.window = dpy->TheWindow;
+ er->xmap.override_redirect = False;
+ break;
+
+ /* The server has called 'XMapWindow' or 'X???' on a client
+ * window */
+ case _RepaintPlease:
+ fprintf(stderr, "_RepaintPlease\n");
+ er = queue_event(dpy);
+ if (!er) return False;
+ er->xexpose.type = Expose;
+ er->xexpose.serial = 0;
+ er->xexpose.send_event = False;
+ er->xexpose.display = dpy;
+ er->xexpose.window = dpy->TheWindow;
+ if (dpy->rotateMode) {
+ er->xexpose.x = dpy->TheWindow->y;
+ er->xexpose.y = dpy->TheWindow->x;
+ er->xexpose.width = dpy->TheWindow->h;
+ er->xexpose.height = dpy->TheWindow->w;
+ }
+ else {
+ er->xexpose.x = dpy->TheWindow->x;
+ er->xexpose.y = dpy->TheWindow->y;
+ er->xexpose.width = dpy->TheWindow->w;
+ er->xexpose.height = dpy->TheWindow->h;
+ }
+ er->xexpose.count = 0;
+ break;
+
+ /* The server has called 'XUnmapWindow' on a client window.
+ *
+ * Need to set lock contended and adjust cliprects (or the
+ * server does).
+ */
+ case _YouveLostFocus:
+ fprintf(stderr, "_YouveLostFocus\n");
+ er = queue_event(dpy);
+ if (!er) return False;
+ er->xunmap.type = UnmapNotify;
+ er->xunmap.serial = 0;
+ er->xunmap.send_event = False;
+ er->xunmap.display = dpy;
+ er->xunmap.event = dpy->TheWindow;
+ er->xunmap.window = dpy->TheWindow;
+ er->xunmap.from_configure = False;
+ break;
- default:
- fprintf(stderr, "Client received unhandled message type %d\n", id);
- shut_fd(dpy, i); /* Actually shuts down the client */
- return False;
+ default:
+ fprintf(stderr, "Client received unhandled message type %d\n", id);
+ shut_fd(dpy, i); /* Actually shuts down the client */
+ return False;
+ }
}
- }
- else {
- switch (id) {
- /* Lets the server know that the client is ready to render
- * (having called 'XMapWindow' locally).
- */
- case _CanIHaveFocus:
- fprintf(stderr, "_CanIHaveFocus\n");
- er = queue_event(dpy);
- if (!er) return False;
- er->xmaprequest.type = MapRequest;
- er->xmaprequest.serial = 0;
- er->xmaprequest.send_event = False;
- er->xmaprequest.display = dpy;
- er->xmaprequest.parent = 0;
- er->xmaprequest.window = (Window)i;
- fprintf(stderr, "queued MapRequest\n");
- break;
-
- /* Both _YouveLostFocus and _IDontWantFocus generate unmap
- * events. The idea is that _YouveLostFocus lets the client
- * know that it has had focus revoked by the server, whereas
- * _IDontWantFocus lets the server know that the client has
- * unmapped its own window.
- */
- case _IDontWantFocus:
- fprintf(stderr, "_IDontWantFocus\n");
- er = queue_event(dpy);
- if (!er) return False;
- er->xunmap.type = UnmapNotify;
- er->xunmap.serial = 0;
- er->xunmap.send_event = False;
- er->xunmap.display = dpy;
- er->xunmap.event = (Window)i;
- er->xunmap.window = (Window)i;
- er->xunmap.from_configure = False;
- break;
-
- default:
- fprintf(stderr, "Server received unhandled message type %d\n", id);
- shut_fd(dpy, i); /* Generates DestroyNotify event */
- return False;
+ else {
+ switch (id) {
+ /* Lets the server know that the client is ready to render
+ * (having called 'XMapWindow' locally).
+ */
+ case _CanIHaveFocus:
+ fprintf(stderr, "_CanIHaveFocus\n");
+ er = queue_event(dpy);
+ if (!er) return False;
+ er->xmaprequest.type = MapRequest;
+ er->xmaprequest.serial = 0;
+ er->xmaprequest.send_event = False;
+ er->xmaprequest.display = dpy;
+ er->xmaprequest.parent = 0;
+ er->xmaprequest.window = (Window)i;
+ fprintf(stderr, "queued MapRequest\n");
+ break;
+
+ /* Both _YouveLostFocus and _IDontWantFocus generate unmap
+ * events. The idea is that _YouveLostFocus lets the client
+ * know that it has had focus revoked by the server, whereas
+ * _IDontWantFocus lets the server know that the client has
+ * unmapped its own window.
+ */
+ case _IDontWantFocus:
+ fprintf(stderr, "_IDontWantFocus\n");
+ er = queue_event(dpy);
+ if (!er) return False;
+ er->xunmap.type = UnmapNotify;
+ er->xunmap.serial = 0;
+ er->xunmap.send_event = False;
+ er->xunmap.display = dpy;
+ er->xunmap.event = (Window)i;
+ er->xunmap.window = (Window)i;
+ er->xunmap.from_configure = False;
+ break;
+
+ default:
+ fprintf(stderr, "Server received unhandled message type %d\n", id);
+ shut_fd(dpy, i); /* Generates DestroyNotify event */
+ return False;
+ }
}
- }
- dpy->fd[i].readbuf_count -= count;
+ dpy->fd[i].readbuf_count -= count;
- /* This probably never happens, but just in case: */
- if (dpy->fd[i].readbuf_count) {
- fprintf(stderr, "count: %d memmove %p %p %d\n", count,
- dpy->fd[i].readbuf + count,
- dpy->fd[i].readbuf,
- dpy->fd[i].readbuf_count);
+ if (dpy->fd[i].readbuf_count) {
+ fprintf(stderr, "count: %d memmove %p %p %d\n", count,
+ dpy->fd[i].readbuf,
+ dpy->fd[i].readbuf + count,
+ dpy->fd[i].readbuf_count);
- memmove(dpy->fd[i].readbuf + count,
- dpy->fd[i].readbuf,
- dpy->fd[i].readbuf_count);
+ memmove(dpy->fd[i].readbuf,
+ dpy->fd[i].readbuf + count,
+ dpy->fd[i].readbuf_count);
+ }
}
return True;
}
+static void __driHandleVtSignals( Display *dpy )
+{
+ dpy->vtSignalFlag = 0;
+
+ if (!dpy->haveVT && dpy->hwActive) {
+ /* Need to get lock and shutdown hardware */
+ DRM_LIGHT_LOCK( dpy->drmFD, dpy->pSAREA, dpy->serverContext );
+/* dpy->driver->shutdownHardware( dpy ); */
+
+ /* Can now give up control of the VT */
+ ioctl( dpy->ConsoleFD, VT_RELDISP, 1 );
+ dpy->hwActive = 0;
+ }
+ else if (dpy->haveVT && !dpy->hwActive) {
+ /* Get VT (wait??) */
+ ioctl( dpy->ConsoleFD, VT_RELDISP, VT_ACTIVATE );
+
+ /* restore HW state, release lock */
+/* dpy->driver->restoreHardware( dpy ); */
+ DRM_UNLOCK( dpy->drmFD, dpy->pSAREA, dpy->serverContext );
+ dpy->hwActive = 1;
+ }
+ else
+ fprintf(stderr, "handle_vt_signals: haveVT %d hwActive %d\n",
+ dpy->haveVT, dpy->hwActive);
+}
+
+
#undef max
#define max(x,y) ((x) > (y) ? (x) : (y))
@@ -432,7 +472,14 @@ __miniglx_Select( Display *dpy, int n, fd_set *rfds, fd_set *wfds, fd_set *xfds,
}
+ if (dpy->vtSignalFlag)
+ __driHandleVtSignals( dpy );
+
retval = select( n, rfds, wfds, xfds, tv );
+
+ if (dpy->vtSignalFlag)
+ __driHandleVtSignals( dpy );
+
if (retval < 0)
return retval;
@@ -470,8 +517,8 @@ __miniglx_Select( Display *dpy, int n, fd_set *rfds, fd_set *wfds, fd_set *xfds,
else {
dpy->fd[i].writebuf_count -= r;
if (dpy->fd[i].writebuf_count) {
- memmove(dpy->fd[i].writebuf + r,
- dpy->fd[i].writebuf,
+ memmove(dpy->fd[i].writebuf,
+ dpy->fd[i].writebuf + r,
dpy->fd[i].writebuf_count);
}
}
@@ -530,6 +577,8 @@ int __miniglx_open_connections( Display *dpy )
perror("unlink " MINIGLX_FIFO_NAME);
return False;
}
+
+ umask( 0000 ); /* open to everybody ? */
}
/* Create a unix socket -- Note this is *not* a network connection!
@@ -553,8 +602,7 @@ int __miniglx_open_connections( Display *dpy )
return False;
}
- /* Wait for confirmation from the server, in the form of a _DriverInfo
- * message.
+ /* Wait for configuration messages from the server.
*/
welcome_message( dpy, 0 );
}
@@ -590,6 +638,29 @@ void __miniglx_close_connections( Display *dpy )
FREE(dpy->fd);
}
+
+static void set_drawable_flag( Display *dpy, int w, int flag )
+{
+ fprintf(stderr, "%s %d %d\n", __FUNCTION__, w, flag);
+
+ if (dpy->pSAREA) {
+ DRM_LIGHT_LOCK( dpy->drmFD, dpy->pSAREA, dpy->serverContext );
+
+ dpy->pSAREA->drawableTable[w].stamp++;
+ dpy->pSAREA->drawableTable[w].flags = flag;
+
+ fprintf(stderr, "%s: stamp now %d\n",
+ __FUNCTION__,
+ dpy->pSAREA->drawableTable[w].stamp);
+
+
+ DRM_UNLOCK( dpy->drmFD, dpy->pSAREA, dpy->serverContext );
+ }
+}
+
+
+
+
/**
* \brief Map Window.
*
@@ -607,6 +678,7 @@ XMapWindow( Display *dpy, Window w )
if (dpy->IsClient)
send_char_msg( dpy, 0, _CanIHaveFocus );
else {
+ set_drawable_flag( dpy, (int)w, 1 );
send_char_msg( dpy, (int)w, _YouveGotFocus );
send_char_msg( dpy, (int)w, _RepaintPlease );
}
@@ -622,11 +694,18 @@ XMapWindow( Display *dpy, Window w )
* it is impossible to force them to keep updating their contents & at
* least this way there is notification that they've stopped.
*
+ * The entrypoint is required for the server in any case.
*/
void
-XUnmapWindow( Display *dpy, Window window )
+XUnmapWindow( Display *dpy, Window w )
{
- send_char_msg( dpy, 0, dpy->IsClient ? _IDontWantFocus : _YouveLostFocus );
+ if (dpy->IsClient) {
+ send_char_msg( dpy, 0, _IDontWantFocus );
+ }
+ else {
+ set_drawable_flag( dpy, (int)w, 0 );
+ send_char_msg( dpy, (int)w, _YouveLostFocus );
+ }
}