Guys,

Looks like you have most of the details right.

Here's what I did for static re-initialization. (Figure 1A & 1B)  Certainly I 
must have missed some things.  For one, I'm not especially thrilled with how I 
hacked Fl_Surface_Device and Fl_Display_Device with set() functions, not how 
the Fl_GDI_Graphics_Driver initialization takes place.  Since these are 
globals, doing reinitialization appears to be dicey.

Regarding Adobe's SDK.  It is a C-based API.  Adobe told me a few years ago 
(CS4?) that they stopped unloading plug-ins between executions for performance. 
 On the Mac that started with CS5 and their Cocoa implementation, but on the PC 
I think it happened earlier.  I notice that dynamic linking happens upon 
startup in CS5 (spotted this with a variant that used FLTKDLL.DLL instead).  
I'm being called with the primary Photoshop thread and need to yield to 
Photoshop if I'm doing heavy processing via a callback to push the progress bar 
and test for the escape key.  This permits events to be checked/handled by 
Photoshop.  Otherwise, my DLL is in charge.

As far as FLTKDLL.DLL testing, I have tried fully unloading the DLL (looping 
until there is no more reference to it) and then reloading it again.  This 
should have had the effect of reinitialization, but the failure the second time 
persisted.  That led me down a path of wondering what happens in the OLE/COM 
world.

My so-called "popup function" could as simple as Figure 2. (Hello World) and it 
still fails the second time.  Actually ->show() fails.  The dialog never 
appears yet we seem to be stuck in the event loop.  The loop used to be 
Fl::run(), but I read some conflicting stuff about multiple windows and thought 
this would be better.  Also notice the Fl::flush() calls.  They made no 
difference.  This fits with Greg's conclusions about the event handling being 
screwed up.  I made an additional test by removing the event loop and instead 
just doing a show/hide combination, and the ->show() call the second time does 
not happen.  Execution continues beyond that line (I assume ->show() is just 
some kind of event post), but no dialog appears.  ->shown() is true, though.

I've gotten approval from the bosses to attempt a two-part plug-in -- first 
part that grabs the image, second part that does the processing/UI.  Now I have 
to do it.  Doing it as a DLL is no biggie -- I've got a lot of experience with 
that, but making part be stand-alone in a different process, and yet not appear 
to be that way will be challenging.  Especially that yield portion (I'd have to 
go async between the two parts so that the Photoshop stub continues to allow 
Photoshop to update).  This gets ugly fast.

So here are my questions:

a) Why does FLTK rely upon exit() on the way out?

b) Does anyone have an idea about how to "save the state" of the GDI, event 
handlers, and OpenGL so it could be easily restored?  This might be the other 
kind of solution.

c) Besides those in Fl_Devices.h, how many other classes have a persistent 
static instantiation?

Also, I have absolutely no objections to contributing to the cause.  I'm pretty 
sure that someone else should be testing and checking in any changes that are 
worthwhile keeping, though. :)

-Chris

-------------------------

Figure 1A: (from Fl.cxx)
#ifdef WIN32
        ///////////////INITIALIZE ALL OF FLTK WIN32 STATICS///////////////
        //__Fl_Reinit (calls __Fl_win32_Reinit() in FL.cxx)
        void __Fl_Reinit(void)
        {
                __Fl_win32_Reinit();    //Fl_win32.cxx
                win32_at_exit.~Fl_Win32_At_Exit();
                OleInitialize(0L);
                handlers = 0;
                dnd_flag = 0;
                num_dwidgets = 0;
                alloc_dwidgets = 0;
                dwidgets = 0;
                widget_watch = 0;
                num_widget_watch = 0;
                max_widget_watch = 0;
        }//__Fl_Reinit

#endif

Figure 1B: (from Fl_win32.cxx)
///////////////INITIALIZE ALL OF FLTK WIN32 STATICS///////////////
//__Fl_win32_Reinit (called by __Fl_Reinit() in FL.cxx)
void __Fl_win32_Reinit(void)
{
        static Fl_GDI_Graphics_Driver l_fl_gdi_driver;
        static Fl_Display_Device l_fl_gdi_display(&l_fl_gdi_driver);

        fl_gdi_driver = l_fl_gdi_driver;
        fl_gdi_display = l_fl_gdi_display;
        fl_graphics_driver = &l_fl_gdi_driver;

        //fl_gdi_display(&fl_gdi_driver);       //<-- ALWAYS FAILS TO COMPILE 
$$$
        //fl_graphics_driver = (Fl_Graphics_Driver*)&fl_gdi_driver; // the 
current target driver of graphics operations
        //Fl_Surface_Device::_surface = (Fl_Surface_Device*)&fl_gdi_display; // 
the current target surface of graphics operations
        //Fl_Display_Device::_display = &fl_gdi_display; // the platform display

        Fl_Surface_Device::set_surface(&fl_gdi_display); // the current target 
surface of graphics operations
        Fl_Display_Device::set_display(&fl_gdi_display); // the platform display

        s_wsock_mod = 0;
        fl_wsk_select_f s_wsock_select = 0;
        fl_wsk_fd_is_set_f fl_wsk_fd_is_set = 0;

        s_imm_module = 0;
        flTypeImmGetContext flImmGetContext = 0;
        flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0;
        flTypeImmReleaseContext flImmReleaseContext = 0;
        flTypeImmIsIME flImmIsIME = 0;

        maxfd = 0;
        nfds = 0;
        fd_array_size = 0;

        fl_aimm = NULL;

        fl_is_ime = 0;

        //I suspect these are the problem:
        fl_gc = 0;
        fl_window = NULL;

        win_DC_list = 0;
}//__Fl_Reinit_FLTK

Figure 1C: (from Fl_Device.H)
  /////////ADDED 8/30/12 - Fl_Surface_Device
  static inline void set_surface(Fl_Surface_Device *a) {_surface = a;};

  /////////ADDED 8/30/12 - Fl_Display_Device
  static inline void set_display(Fl_Display_Device *a) {_display = a;};



Figure 2: (Error Message dialog, based upon Hello World)
static char __message[256];
static char __title[256];
int ErrorMessage(const char *title, const char *message)
{
        strcpy(__title, title);
        strcpy(__message, message);
        Fl_Window *window = new Fl_Window(40,100,340,180, __title);
        window->set_modal();
        Fl_Box *box = new Fl_Box(0,0,340,180,__message);
        box->box(FL_UP_BOX);
        box->labelsize(24);
        window->end();
        window->show(0, NULL);                  //doesn't appear to actually 
show the second time.
        Fl::flush();                            //allow dialog to appear prior 
to event loop?
        while(window->visible())                //functionally an infinite loop 
the second time.
                Fl::wait();
        Fl::flush();                            //never gets here the second 
time
        return 0;
}//ErrorMessage



> Chris et al,
>
> Can I just summarise what I *think* is being done here, to make sure I actu=
> ally understand the question?
>
> So...
>
> - I imagine that PS calls a function with a C API (and perhaps provides e.g=
> .. callbacks, also with C API, to allow the called function to interact with=
>  the PS instance.)
>
> - The called function is used to pop-up some GUI written in fltk, which I a=
> ssume calls Fl::run();
>
> - When the pop-up closes, the function returns to PS.
>
>
> Observed behaviours are...
>
> - The first time this is invoked, the pop-up appears just fine and it all J=
> ust Works.
>
> - On subsequent attempts, the GUI simply never appears...
>
>
> We think that...
>
> - PS does not unload the fltk DLL after the first pass
>
> - Attempts to unload the DLL on purpose don't seem to help
>
> - The OP (Chris) has made some attempts to "reset" the fltk static context =
> between runs, but that doesn't seem to have helped
>
> - Other stuff...?
>
>
> Looking at Fl.cxx, I wondered about:
>
> - the "Check" list (near line 342) - can we (should we? do we?) reset that =
> between runs of the pop-up?
>
> - the oleInitialized stuff, and win32_at_exit instance - can we (should we)=
>  trigger that manually when the pop-up expires to get things ready for the =
> next time?
>
> - Fl_X::first (near line 657) do we need to clean that up...?
>
>
>
> Also: What does the Chris do in the pop-up function? =
>
>
> I imagine that the first time in, this creates all the fltk windows and wid=
> gets that are needed.
>
> Now, does it tear them down on pop-up exit, then re-create them on the next=
>  call?
>
> Or, should it create them on the first call, but retain them and re-use the=
> m on subsequent calls? Would that be better? Would that perhaps avoid the r=
> e-init issues we seem to be seeing?
>
>
> Thoughts?
>
>
>
> SELEX Galileo Ltd
> Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS=
> 14 3EL
> A company registered in England & Wales.  Company no. 02426132
> ********************************************************************
> This email and any attachments are confidential to the intended
> recipient and may also be privileged. If you are not the intended
> recipient please delete it from your system and notify the sender.
> You should not copy it or use it for any purpose nor disclose or
> distribute its contents to any other person.
> ********************************************************************
>

_______________________________________________
fltk mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to