diff options
author | Jose Fonseca <j_r_fonseca@yahoo.co.uk> | 2003-05-18 12:36:26 +0000 |
---|---|---|
committer | Jose Fonseca <j_r_fonseca@yahoo.co.uk> | 2003-05-18 12:36:26 +0000 |
commit | be881cdee1055f2d274332b0cf28d419b53a0335 (patch) | |
tree | dc4be2f8c9158d24870e311c5289adde08ad401d /src | |
parent | 7fe70b51e82516b8acc0ebdfc4fd2bdfefecac2c (diff) |
Update the documentation for the new miniglx server-client architecture.
Diffstat (limited to 'src')
-rw-r--r-- | src/miniglx/dri_util.c | 15 | ||||
-rw-r--r-- | src/miniglx/miniglx.c | 72 | ||||
-rw-r--r-- | src/miniglx/miniglxP.h | 35 | ||||
-rw-r--r-- | src/miniglx/miniglx_events.c | 202 |
4 files changed, 227 insertions, 97 deletions
diff --git a/src/miniglx/dri_util.c b/src/miniglx/dri_util.c index f67a2a3137..dee825e7d7 100644 --- a/src/miniglx/dri_util.c +++ b/src/miniglx/dri_util.c @@ -67,7 +67,7 @@ __driUtilMessage(const char *f, ...) * \brief Find a visual. * * \param dpy the display handle. - * \param screen the screen number. It is currently ignored and should be zero. + * \param scrn the screen number. It is currently ignored and should be zero. * \param vid visual ID. * * \return pointer to the wanted __GLXvisualConfigRec if found, or NULL otherwise. @@ -341,7 +341,9 @@ static void driDestroyDrawable(Display *dpy, void *drawablePrivate) * \param dpy the display handle. * \param scrn the screen number. * \param draw the GLX drawable info. + * \param vid visual ID. * \param pdraw will receive the drawable dependent methods. + * * * \returns a opaque pointer to the per-drawable private info on success, or NULL * on failure. @@ -424,6 +426,7 @@ static void *driCreateDrawable(Display *dpy, int scrn, * * \param dpy the display handle. * \param draw the GLX drawable. + * \param screenPrivate opaque pointer to the per-screen private information. * * \return pointer to a __DRIdrawableRec structure. * @@ -476,7 +479,6 @@ static void driDestroyContext(Display *dpy, int scrn, void *contextPrivate) * \brief Create the per-drawable private driver information. * * \param dpy the display handle. - * \param scrn the screen number. * \param vis the visual information. * \param sharedPrivate the shared context dependent methods or NULL if non-existent. * \param pctx will receive the context dependent methods. @@ -591,6 +593,9 @@ static void driDestroyScreen(Display *dpy, int scrn, void *screenPrivate) * \param dpy the display handle. * \param scrn the screen number. * \param psc will receive the screen dependent methods. + * \param numConfigs number of visuals. + * \param config visuals. + * \param driverAPI driver callbacks structure. * * \return a pointer to the per-screen private information. * @@ -599,6 +604,8 @@ static void driDestroyScreen(Display *dpy, int scrn, void *screenPrivate) * opens the DRM device verifying that the exported version matches the * expected. It copies the driver callback functions and calls * __DriverAPIRec::InitDriver. + * + * If a client maps the framebuffer and SAREA regions. */ __DRIscreenPrivate * __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, @@ -726,6 +733,10 @@ __driUtilCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, * * \param dpy the display handle. * \param scrn the screen number. + * \param psc pointer to the screen dependent methods structure. + * \param numConfigs number of visuals. + * \param config visuals. + * \param driverAPI driver callbacks structure. * * \internal * Same as __driUtilCreateScreen() but without opening the DRM device. diff --git a/src/miniglx/miniglx.c b/src/miniglx/miniglx.c index cd83e6fb17..158be0a530 100644 --- a/src/miniglx/miniglx.c +++ b/src/miniglx/miniglx.c @@ -1,3 +1,12 @@ +/** + * \file miniglx.c + * \brief Mini GLX interface functions. + * \author Brian Paul + * + * The Mini GLX interface is a subset of the GLX interface, plus a + * minimal set of Xlib functions. + */ + /* * Mesa 3-D graphics library * Version: 5.0 @@ -22,18 +31,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* $Id: miniglx.c,v 1.1.4.53 2003/04/26 21:17:47 keithw Exp $ */ - - -/** - * \file miniglx.c - * \brief Mini GLX interface functions. - * \author Brian Paul - * - * The Mini GLX interface is a subset of the GLX interface, plus a - * minimal set of Xlib functions. - */ - +/* $Id: miniglx.c,v 1.1.4.54 2003/05/18 12:36:26 jrfonseca Exp $ */ /** * \mainpage Mini GLX @@ -352,11 +350,10 @@ OpenFBDev( Display *dpy ) * \brief Setup up the desired framebuffer device mode. * * \param dpy the display handle. - * \param win the window handle, from which the screen size is taken. * * \return GL_TRUE on success, or GL_FALSE on failure. * - * \sa This is called during XCreateWindow(). + * \sa This is called during __miniglx_StartServer(). * * \internal * @@ -926,6 +923,9 @@ static int InitDriver( Display *dpy ) * Asks the driver for a list of supported visuals. Performs the per-screen * client-side initialization. Also setups the callbacks in the screen private * information. + * + * Does the framebuffer device setup. Calls __miniglx_open_connections() to + * serve clients. */ Display * __miniglx_StartServer( const char *display_name ) @@ -996,14 +996,30 @@ __miniglx_StartServer( const char *display_name ) } - /* Need to: - * - read config file (get driver name) - * - but what about virtualWidth, etc? - * - load driver module - * - determine dpy->driverClientMsgSize, - * - allocate dpy->driverClientMsg - */ - +/** + * \brief Initialize the graphics system. + * + * \param display_name currently ignored. It is recommended to pass it as NULL. + * \return a pointer to a #Display if the function is able to initialize + * the graphics system, NULL otherwise. + * + * Allocates a MiniGLXDisplayRec structure and fills in with information from a + * configuration file. + * + * Calls __miniglx_open_connections() to connect to the server. + * + * Loads the DRI driver and pulls in Mini GLX specific hooks into a + * DRIDriverRec structure, and the standard DRI \e __driCreateScreen hook. + * Asks the driver for a list of supported visuals. Performs the per-screen + * client-side initialization. Also setups the callbacks in the screen private + * information. + * + * \todo + * - read config file + * - what about virtualWidth, etc? + * - determine dpy->driverClientMsgSize, + * - allocate dpy->driverClientMsg + */ Display * XOpenDisplay( const char *display_name ) { @@ -1083,11 +1099,13 @@ XOpenDisplay( const char *display_name ) * * \param dpy display handle. It becomes invalid at this point. * - * If there is a window open calls XDestroyWindow(). + * Destroys the window if any, and destroys the per-screen + * driver private information. + * Calls __miniglx_close_connections(). + * + * If a server, puts the the framebuffer back into the initial state. * - * Destroys the per-screen driver private information and asks the driver to - * halt the framebuffer device before unloading it. Closes the framebuffer - * device. Finally frees the display structure. + * Finally frees the display structure. */ void XCloseDisplay( Display *dpy ) @@ -1250,7 +1268,7 @@ XCreateWindow( Display *display, Window parent, int x, int y, * \param display display handle. * \param w window handle. * - * This function frees window \p w. + * This function calls XUnmapWindow() and frees window \p w. * * In case of destroying the current buffer first unbinds the GLX context * by calling glXMakeCurrent() with no drawable. diff --git a/src/miniglx/miniglxP.h b/src/miniglx/miniglxP.h index 0049a8a9a1..78aeff5eab 100644 --- a/src/miniglx/miniglxP.h +++ b/src/miniglx/miniglxP.h @@ -194,12 +194,11 @@ struct DRIDriverContextRec { void *MMIOAddress; /**< \brief start of the mmap'd MMIO region */ /** - * \name Client configuration details + * \brief 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; @@ -211,7 +210,6 @@ struct DRIDriverContextRec { int virtualHeight; } shared; - /*@}*/ /** * \name From DRIInfoRec */ @@ -364,12 +362,18 @@ struct MiniGLXContextRec { #define MINIGLX_EVENT_QUEUE_SZ 16 #define MINIGLX_EVENT_QUEUE_MASK (MINIGLX_EVENT_QUEUE_SZ-1) +/** + * A connection to/from the server + * + * All information is to/from the server is buffered and then dispatched by + * __miniglx_Select() to avoid blocking the server. + */ struct MiniGLXConnection { - int fd; - char readbuf[MINIGLX_BUF_SIZE]; - char writebuf[MINIGLX_BUF_SIZE]; - int readbuf_count; - int writebuf_count; + int fd; /**< \brief file descriptor */ + char readbuf[MINIGLX_BUF_SIZE]; /**< \brief read buffer */ + char writebuf[MINIGLX_BUF_SIZE]; /**< \brief write buffer */ + int readbuf_count; /**< \brief counf of bytes waiting to be read */ + int writebuf_count; /**< \brief counf of bytes waiting to be written */ }; @@ -381,7 +385,7 @@ struct MiniGLXConnection { struct MiniGLXDisplayRec { /** \brief fixed framebuffer screen info */ struct fb_fix_screeninfo FixedInfo; - /** \brief original and current variable frambuffer screen info */ + /** \brief original and current variable framebuffer screen info */ struct fb_var_screeninfo OrigVarInfo, VarInfo; struct sigaction OrigSigUsr1; struct sigaction OrigSigUsr2; @@ -393,13 +397,16 @@ struct MiniGLXDisplayRec { int rotateMode; - volatile int vtSignalFlag, haveVT; - int hwActive; + volatile int vtSignalFlag; + volatile int haveVT; /**< \brief whether the VT is hold */ + int hwActive; /**< \brief whether the hardware is active -- mimics + the variations of MiniGLXDisplayRec::haveVT */ - int IsClient, clientID; - int nrFds; - struct MiniGLXConnection *fd; + int IsClient; /**< \brief whether it's a client or the server */ + int clientID; + int nrFds; /**< \brief number of connections (usually just one for the clients) */ + struct MiniGLXConnection *fd; /**< \brief connections */ struct { int nr, head, tail; diff --git a/src/miniglx/miniglx_events.c b/src/miniglx/miniglx_events.c index 7d63c607c2..a0457a5e39 100644 --- a/src/miniglx/miniglx_events.c +++ b/src/miniglx/miniglx_events.c @@ -1,3 +1,19 @@ +/** + * \file miniglx_events.c + * \brief Mini GLX client/server communication functions. + * \author Keith Whitwell + * + * The Mini GLX interface is a subset of the GLX interface, plus a + * minimal set of Xlib functions. This file adds interfaces to + * arbitrate a single cliprect between multiple direct rendering + * clients. + * + * A fairly complete client/server non-blocking communication + * mechanism. Probably overkill given that none of our messages + * currently exceed 1 byte in length and take place over the + * relatively benign channel provided by a unix domain socket. + */ + /* * Mesa 3-D graphics library * Version: 5.0 @@ -22,25 +38,9 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* $Id: miniglx_events.c,v 1.1.2.11 2003/04/28 13:21:10 keithw Exp $ */ +/* $Id: miniglx_events.c,v 1.1.2.12 2003/05/18 12:36:26 jrfonseca Exp $ */ -/** - * \file miniglx_events.c - * \brief Mini GLX client/server communication functions. - * \author Keith Whitwell - * - * The Mini GLX interface is a subset of the GLX interface, plus a - * minimal set of Xlib functions. This file adds interfaces to - * arbitrate a single cliprect between multiple direct rendering - * clients. - * - * A fairly complete client/server non-blocking communication - * mechanism. Probably overkill given that none of our messages - * currently exceed 1 byte in length and take place over the - * relatively benign channel provided by a unix domain socket. - */ - #include <assert.h> #include <errno.h> #include <signal.h> @@ -69,7 +69,7 @@ #define MINIGLX_FIFO_NAME "/tmp/miniglx.fifo" - +/** Character messages. */ enum msgs { _CanIHaveFocus, _IDontWantFocus, @@ -213,16 +213,18 @@ static int send_char_msg( Display *dpy, int i, char msg ) /** - * \brief Block and recieve a message from a socket connection. + * \brief Block and receive a message from a socket connection. * * \param dpy the display handle. * \param connection the index in dpy->fd of the socket connection. * \param msg storage for the recieved message. * \param msg_size the number of bytes to read. * - * \internal Block and read from the connection's file descriptor - * until msg_size bytes have been received. Only called from - * welcome_message_part(). + * \internal + * Block and read from the connection's file descriptor + * until msg_size bytes have been received. + * + * Only called from welcome_message_part(). */ static int blocking_read( Display *dpy, int connection, char *msg, size_t msg_size ) @@ -241,8 +243,23 @@ static int blocking_read( Display *dpy, int connection, return True; } - - +/** + * \brief Send/receive a part of the welcome message. + * + * \param dpy the display handle. + * \param i the index in dpy->fd of the socket connection. + * \param msg storage for the sent/received message. + * \param sz the number of bytes to write/read. + * + * \return True on success, or False on failure. + * + * This function is called by welcome_message_part(), to either send or receive + * (via blocking_read()) part of the welcome message, according to whether + * Display::IsClient is set. + * + * Each part of the welcome message on the wire consists of a count and then the + * actual message data with that number of bytes. + */ static int welcome_message_part( Display *dpy, int i, void **msg, int sz ) { if (dpy->IsClient) { @@ -260,6 +277,18 @@ static int welcome_message_part( Display *dpy, int i, void **msg, int sz ) return True; } +/** + * \brief Send/receive the welcome message. + * + * \param dpy the display handle. + * \param i the index in dpy->fd of the socket connection. + * + * \return True on success, or False on failure. + * + * Using welcome_message_part(), sends/receives the client ID, the client + * configuration details in DRIDriverContext::shared, and the driver private + * message in DRIDriverContext::driverClientMsg. + */ static int welcome_message( Display *dpy, int i ) { void *tmp = &dpy->driverContext.shared; @@ -281,21 +310,14 @@ static int welcome_message( Display *dpy, int i ) /** - * \brief Do the first part of setting up the framebuffer device. + * \brief Handle a new client connection. * * \param dpy the display handle. * - * \return GL_TRUE on success, or GL_FALSE on failure. + * \return True on success or False on failure. * - * \sa This is called during XOpenDisplay(). - * - * \internal - * Gets the VT number, opens the respective console TTY device. Saves its state - * to restore when exiting and goes into graphics mode. - * - * Opens the framebuffer device and make a copy of the original variable screen - * information and gets the fixed screen information. Maps the framebuffer and - * MMIO region into the process address space. + * Acepts the connection, sets it in non-blocking operation, and finds a free + * slot in Display::fd for it. */ static int handle_new_client( Display *dpy ) { @@ -349,9 +371,19 @@ static int handle_new_client( Display *dpy ) return False; } -/* This routine "puffs out" the very basic communciations between +/** + * This routine "puffs out" the very basic communciations between * client & server to full-sized X Events that can be handled by the * application. + * + * \param dpy the display handle. + * \param i the index in dpy->fd of the socket connection. + * + * \return True on success or False on failure. + * + * \internal + * Interprets the message (see msg) into a XEvent and advances the file FIFO + * buffer. */ static int handle_fifo_read( Display *dpy, int i ) @@ -478,6 +510,17 @@ handle_fifo_read( Display *dpy, int i ) return True; } +/** + * Handle a VT signal + * + * \param dpy display handle. + * + * The VT switches is detected by comparing Display::haveVT and + * Display::hwActive. When loosing the VT the hardware lock is acquired, the + * hardware is shutdown via a call to DRIDriverRec::shutdownHardware(), and the + * VT released. When aquiring the VT back the hardware state is restored via a + * call to DRIDriverRec::restoreHardware() and the hardware lock released. + */ static void __driHandleVtSignals( Display *dpy ) { dpy->vtSignalFlag = 0; @@ -513,12 +556,35 @@ static void __driHandleVtSignals( Display *dpy ) #undef max #define max(x,y) ((x) > (y) ? (x) : (y)) -/* This all looks pretty complex, but is necessary especially on the +/** + * Logic for the select() call. + * + * \param dpy display handle. + * \param n highest fd in any set plus one. + * \param rfds fd set to be watched for reading, or NULL to create one. + * \param wfds fd set to be watched for writing, or NULL to create one. + * \param xfds fd set to be watched for exceptions or error, or NULL to create one. + * \param tv timeout value, or NULL for no timeout. + * + * \return number of file descriptors contained in the sets, or a negative number on failure. + * + * \note + * This all looks pretty complex, but is necessary especially on the * server side to prevent a poorly-behaved client from causing the * server to block in a read or write and hence not service the other * clients. * + * \sa * See select_tut in the linux manual pages for more discussion. + * + * \internal + * Creates and initializes the file descriptor sets by inspecting Display::fd + * if these aren't passed in the function call. Calls select() and fullfill the + * demands by trying to fill MiniGLXConnection::readbuf and draining + * MiniGLXConnection::writebuf. + * The server fd[0] is handled specially for new connections, by calling + * handle_new_client(). + * */ int __miniglx_Select( Display *dpy, int n, fd_set *rfds, fd_set *wfds, fd_set *xfds, @@ -638,6 +704,17 @@ __miniglx_Select( Display *dpy, int n, fd_set *rfds, fd_set *wfds, fd_set *xfds, return retval; } +/** + * \brief Handle socket events. + * + * \param dpy the display handle. + * \param nonblock whether to return immediatly or wait for an event. + * + * \return True on success, False on failure. Aborts on critical error. + * + * \internal + * This function is the select() main loop. + */ static int handle_fd_events( Display *dpy, int nonblock ) { while (1) { @@ -652,8 +729,18 @@ static int handle_fd_events( Display *dpy, int nonblock ) } } - - +/** + * Initializes the connections. + * + * \param dpy the display handle. + * + * \return True on success or False on failure. + * + * Allocates and initializes the Display::fd array and create a unix socket on + * the first entry. For a server binds the socket to a filename and listen for + * connections. For a client connects to the server and waits for a welcome + * message. Sets the socket in nonblocking mode. + */ int __miniglx_open_connections( Display *dpy ) { struct sockaddr_un sa; @@ -733,6 +820,11 @@ int __miniglx_open_connections( Display *dpy ) } +/** + * Frees the connections initialzed by __miniglx_open_connections(). + * + * \param dpy the display handle. + */ void __miniglx_close_connections( Display *dpy ) { int i; @@ -749,6 +841,16 @@ void __miniglx_close_connections( Display *dpy ) } +/** + * Set a drawable flag. + * + * \param dpy the display handle. + * \param w drawable (window). + * \param flag flag. + * + * Sets the specified drawable flag in the SAREA and increment its stamp while + * holding the light hardware lock. + */ static void set_drawable_flag( Display *dpy, int w, int flag ) { if (dpy->driverContext.pSAREA) { @@ -769,11 +871,10 @@ static void set_drawable_flag( Display *dpy, int w, int flag ) - /** * \brief Map Window. * - * \param display the display handle as returned by XOpenDisplay(). + * \param dpy the display handle as returned by XOpenDisplay(). * \param w the window handle. * * If called by a client, sends a request for focus to the server. If @@ -798,7 +899,7 @@ XMapWindow( Display *dpy, Window w ) /** * \brief Unmap Window. * - * \param display the display handle as returned by XOpenDisplay(). + * \param dpy the display handle as returned by XOpenDisplay(). * \param w the window handle. * * Called from the client: Lets the server know that the window won't @@ -825,11 +926,11 @@ XUnmapWindow( Display *dpy, Window w ) /** * \brief Block and wait for next X event. * - * \param display the display handle as returned by XOpenDisplay(). + * \param dpy the display handle as returned by XOpenDisplay(). * \param event_return a pointer to an XEvent struct for the returned data. * * Wait until there is a new XEvent pending. - **/ + */ int XNextEvent(Display *dpy, XEvent *event_return) { for (;;) { @@ -843,13 +944,13 @@ int XNextEvent(Display *dpy, XEvent *event_return) /** * \brief Non-blocking check for next X event. * - * \param display the display handle as returned by XOpenDisplay(). - * \param event_mask IGNORED + * \param dpy the display handle as returned by XOpenDisplay(). + * \param event_mask ignored. * \param event_return a pointer to an XEvent struct for the returned data. * * Check if there is a new XEvent pending. Note that event_mask is * ignored and any pending event will be returned. - **/ + */ Bool XCheckMaskEvent(Display *dpy, long event_mask, XEvent *event_return) { if ( dpy->eventqueue.head != dpy->eventqueue.tail ) @@ -859,10 +960,3 @@ Bool XCheckMaskEvent(Display *dpy, long event_mask, XEvent *event_return) return dequeue_event( dpy, event_return ); } - - - - - - -/*@}*/ |