On Fri, 14 Jun 2002 21:33:30 +0200 Till Adam <till@...> babbled:
> I dont really see why that would be any cleaner than having one setup call per
> engine, considering the fact that the number of engines will likely be less
> than maybe 10. With the void * and structs solution you'll have to trust the
> user to fill in that struct correctly and not forget about a member and then
> access it more or less blindly, whereas a function signature get checked by
> the compiler. So I think its less safe and its not less work.
ok. i have a plan.. well.. too late. i implemented it...
ok - however we look we can't get the compiler to do it all for us. basically
because that's done compile time.. bu the lib may change runtime (ie the lib may
be recompiled with or without other engines at some later date etc. and the app
should not need a recompile, and vice-versa).
eg: app is compiled to use dfb engine OR x11. you download app. it won't even be
able to start because even though it might not be configured to use the dfb
engine it has references to dfb engine symbols for dfb engine init/query etc. it
won't even get past ld.so.
so... we're screwed however we look at it. (i've spent the last few days looking
at it many ways). i've taken suggestions to mind and think i have a good
compromise that keeps it all very very clean.
i suggest checking out my commit. now init is done via an engine-specific struct
(that i need to break the definition of out into its own engine specific
now it's fairly simple yet massively expandable and flexible.
app wants to use engine X
app queries for a listing of engines and see if X is in it.if it isn't it can
try another engine it knows about - or cleanly abort. if it's there then the app
knew about it compile time and has its header for its inti struct. it gets the
init struct from the evas, fills it in, can call functions that are set up in
the struct by the enigne to get information... and then pass struct back in
(evas internally checks that its the same struct and not some dummy new one that
didn't come from the evas - it's not foolproof - but will get the majority of
cases). and then evas can init from that info.
evas = evas_new();
evas_output_size_set(evas, win_w, win_h);
evas_output_viewport_set(evas, 0, 0, win_w, win_h);
einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(evas);
einfo->info.display = disp;
einfo->info.visual = einfo->func.best_visual_get(disp, screen);
einfo->info.colormap = einfo->func.best_colormap_get(disp, screen);
einfo->info.depth = einfo->func.best_depth_get(disp, screen);
einfo->info.drawable = win;
einfo->info.rotation = 0;
evas_engine_info_set(evas, (Evas_Engine_Info *)einfo);
our engine specific header has:
/* FIXME: this should go into another .h file the app needs to include like */
/* Evas_Engine_Software_X11.h */
typedef struct _Evas_Engine_Info_Software_X11 Evas_Engine_Info_Software_X11;
/* PRIVATE - don't mess with this baby or evas will poke its tongue out */
/* at you and make nasty noises */
/* engine specific data & parameters it needs to set up */
/* engine specific function calls to query stuff about the destination */
/* engine (what visual & colormap & depth to use, performance info etc. */
Visual * (*best_visual_get) (Display *disp, int screen);
Colormap (*best_colormap_get) (Display *disp, int screen);
int (*best_depth_get) (Display *disp, int screen);
Evas_Performance *(*performance_test) (Evas *e, Display *disp,
Visual *vis, Colormap cmap, Drawable draw, int depth); void
(*performance_free) (Evas_Performance *perf); char *
(*performance_data_get) (Evas_Performance *perf); char *
(*performance_key_get) (Evas_Performance *perf); Evas_Performance
*(*performance_new) (Evas *e, Display *disp, Visual *vis, Colormap
cmap, Drawable draw, int depth); void (*performance_build)
(Evas_Performance *perf, const char *data); void
(*performance_device_store) (Evas_Performance *perf); } func;
now there are no symbol problems. we still rely on the app properly checking the
einfo is not NULL (sorry i don't check here - but if the app initialized an evas
with an engine id it doesn't handle einfo WILL be NULL) and relies on the struct
not being mutilated and the app passing it back properly, but all in all it's
about the cleanest method i can come up with that supports querying of the
engine, passing in of parameters, and can survive the app and lib having
different ideas of what engines are included, as long as the app "plays nice"
and checks for the engine it wants.
> If you do what you suggest and go the struct and void* route, you could always
> use the same approach and just have one query call which returns a void* to
> the init struct. Just as unsafe, though. ;)
yup, but as i said - i can't think of anything thats safe AND would survive the
lib and app having different compilations of engines
at the end of the day i think i'd rely on a higher level library that would
encapsulate the basics of the target windowing system and its event system and
an event loop that would "do the right thing" here at this interface level, and
take the work from the app.
--------------- Codito, ergo sum - "I code, therefore I am" --------------------
The Rasterman (Carsten Haitzler) raster@...
Mobile Phone: +61 (0)413 451 899 Home Phone: 02 9698 8615