From: Vincent T. <vt...@un...> - 2007-12-31 16:25:47
|
On Sun, 30 Dec 2007, Nathan Ingersoll wrote: >> Another possibility (raster's idea) for >> ecore_x_drawable_geometry_get_async is to sent an event >> ECORE_X_REPLY_GEOMETRY_GET just when the xcb_get_geometry_reply call has >> returned. The event would contain (actually, would be) the structure >> above. Then, the prototype would just be: >> >> void ecore_x_drawable_geometry_get_async(Ecore_X_Drawable drawable (unused)) >> >> raster: in that case, should we also add those events in the Xlib >> implementation ? > > My preference would be a resounding YES! :-) I also tend to agree with > raster's API choice of using the existing event model. > > I would like to see the removal of the _async calls entirely and get > this to the point where we have essentially 2 exposed calls. The first > is the traditional blocking call, while the second is a _request or > _prefetch call. Below are my ideas of how this could work, but you are > far more familiar with the XCB specifics so please let me know if a > part of this is not feasible. There is also the possibility that > extensions could be made to XCB to support some of this behavior. > > For the traditional blocking call the XCB backend would use the > request call, but would immediately request the response value and > cause the app to block. In the Xlib implementation, it would simply > make the blocking call, and return the values as they currently do. > > The request or prefetch call would submit the request and add the > cookie to a queue along with a reply specific callback (similar to the > API rephorm mentioned). This queue would then be processed as part of > the idle loop when the fd for the XCB connection has data available. > Each cookie on the queue would be checked to see if a reply has been > received, or better yet, XCB provides a list of available replies. For > each cookie with a pending reply, it is processed with the reply > specific callback. The callback is responsible for requesting the > data, which we know is available and therefore should not block, and > emitting the ecore event. The Xlib backend would have a blocking call > occur and emit the same event immediately after the blocking call > returns. > > This seems very similar to your proposal but I think it's more > explicit about the expectations the end-user should have for requests. > It should make them realize that the responses are asynchronous events > and that they are potentially slow round trips that will return at > some arbitrary time in the future. Here is a small implementation of your ideas for the GetGeometry request: [code] typedef struct Ecore_X_Cookie Ecore_X_Cookie; typedef struct { int x, y, w, h, border, depth; } Ecore_X_Reply_Get_Geometry; struct Ecore_X_Cookie { xcb_get_geometry_cookie_t cookie; void (*reply) (Ecore_X_Cookie *cookie); }; /* The event */ ECORE_X_REPLY_GET_GEOMETRY /* the prefetch function */ void ecore_x_get_geometry_prefetch (xcb_drawable_t draw) { Ecore_X_Cookie *cookie; cookie = calloc (1, sizeof (Ecore_X_Cookie)); if (!cookie) return; cookie.cookie = xcb_get_geometry_unchecked (_ecore_xcb_conn, draw); cookie.reply = _ecore_xcb_reply_get_geometry; /* add the cookie to an ecore list */ ecore_xcb_cookie_cache (cookie); } /* the callback that is called when its reply is available */ void _ecore_x_reply_get_deometry (Ecore_X_Cookie *cookie) { xcb_get_geometry_reply_t *reply; Ecore_X_Reply_Get_Geometry *r; reply = xcb_get_geometry (_ecore_xcb_conn, cookie.cookie, NULL); if (!reply) return; r = calloc (1, sizeof (Ecore_X_Reply_Get_Geometry)); if (!r) { free (reply); return; } r->x = reply->x; r->y = reply->y; r->w = reply->w; r->h = reply->h; r->border = reply->border; r->depth = reply->depth; ecore_event_add (ECORE_X_REPLY_GET_GEOMETRY, r, NULL, NULL); ecore_xcb_cookie_remove (cookie); } /* like the events (see ecore_x.c or ecore_xcb.c), */ /* if the fd receives data */ /* (in _ecore_xcb_fd_handler ?) */ /* or somewhere else ?? */ Ecore_X_Cookie *cookie; void *reply; ecore_xcb_cookie_begin (); while (cookie = ecore_xcb_cookie_next()) { if (xcb_poll_for_reply (_ecore_xcb_conn, cookie.cookie, &reply, NULL)) cookie.reply (cookie); } [/code] what do you think of that code ? Vincent |