home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libmocha / et_moz.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  76.4 KB  |  2,876 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*
  19.  * Event handling in the Navigator / libmocha
  20.  *
  21.  * This file contains common code for separate threads to send messages
  22.  *   to the mozilla thread to get it to do stuff
  23.  */
  24. #include "lm.h"
  25. #include "xp.h"
  26. #include "fe_proto.h"
  27. #include "net.h"
  28. #include "structs.h"
  29. #include "prthread.h"
  30. #include "prmem.h"
  31. #include "ds.h"        /* XXX required by htmldlgs.h */
  32. #include "htmldlgs.h"
  33. #include "layout.h"
  34. #include "np.h"
  35. #include "prefapi.h"
  36. #include "pa_parse.h"
  37.  
  38. #define IL_CLIENT
  39. #include "libimg.h"             /* Image Library public API. */
  40.  
  41. /* pointer to the mocha thread */
  42. extern PRThread            *lm_InterpretThread;
  43. extern PRThread            *mozilla_thread;
  44. extern QueueStackElement    *et_TopQueue;
  45.  
  46. /****************************************************************************/
  47.  
  48. PR_STATIC_CALLBACK(void*)
  49. et_PostEvent(ETEvent * e, Bool sync)
  50. {
  51.  
  52.     /* 
  53.      * Guard against the mozilla_event_queue goes away before we do
  54.      *   on exit.
  55.      */
  56.     if(!mozilla_event_queue)
  57.         return(NULL);
  58.  
  59.     /*
  60.      * If we are already in the mozilla thread and about to send
  61.      *   a synchronous message to ourselves just process it right
  62.      *   now instead of deadlocking
  63.      */
  64.     if(sync && PR_CurrentThread() == mozilla_thread) {
  65.     void * val;
  66.     val = e->event.handler(&e->event);
  67.     e->event.destructor(&e->event);
  68.         return(val);
  69.     }
  70.  
  71.     if(sync)
  72.         return(PR_PostSynchronousEvent(mozilla_event_queue, &e->event));
  73.  
  74.     PR_PostEvent(mozilla_event_queue, &e->event);
  75.     return(NULL);
  76.  
  77. }
  78.  
  79.  
  80. /* 
  81.  * synchonous events can't be destroyed until after PR_PostSynchronousEvent()
  82.  *   has returned.  This is a dummy destructor to make sure the event stays
  83.  *   alive along enough
  84.  */
  85. PR_STATIC_CALLBACK(void)
  86. et_DestroyEvent_WaitForIt(void * event)
  87. {
  88. }
  89.  
  90. /*
  91.  * Generic destructor for event with no private data
  92.  */
  93. PR_STATIC_CALLBACK(void)
  94. et_DestroyEvent_GenericEvent(void * event)
  95. {
  96.     XP_FREE(event);
  97. }
  98.  
  99.  
  100. /****************************************************************************/
  101.  
  102. typedef struct {
  103.     ETEvent   ce;
  104.     char*     szMessage;  /* message for dialog */
  105.     JSBool    bConfirm;   /* TRUE if confirmation, FALSE if alert */
  106. } MozillaEvent_MessageBox;
  107.  
  108.  
  109. PR_STATIC_CALLBACK(void*)
  110. et_HandleEvent_MessageBox(MozillaEvent_MessageBox* e)
  111. {
  112.     void *pRet;
  113.     Bool bPriorJSCalling = FALSE;
  114.     if( e->ce.context ) {
  115.         bPriorJSCalling = e->ce.context->bJavaScriptCalling;
  116.         e->ce.context->bJavaScriptCalling = TRUE;
  117.     }
  118.     
  119.     pRet = (void *)JSTYPE_BOOLEAN;
  120.     
  121.     if( e->bConfirm )
  122.         pRet = (void *)FE_Confirm(e->ce.context, e->szMessage);
  123.     else
  124.         FE_Alert(e->ce.context, e->szMessage);
  125.  
  126.     if( e->ce.context ) 
  127.         e->ce.context->bJavaScriptCalling = bPriorJSCalling;
  128.             
  129.     return pRet;
  130. }
  131.  
  132. PR_STATIC_CALLBACK(void)
  133. et_DestroyEvent_MessageBox(MozillaEvent_MessageBox* event)
  134. {
  135.     XP_FREE((char*)event->szMessage);
  136.     XP_FREE(event);
  137. }
  138.  
  139. JSBool
  140. ET_PostMessageBox(MWContext* context, char* szMessage, JSBool bConfirm)
  141. {
  142.     JSBool ok = JS_TRUE;
  143.     MozillaEvent_MessageBox* event = PR_NEW(MozillaEvent_MessageBox);
  144.     if (event == NULL) 
  145.         return(JS_FALSE);
  146.     event->ce.context = context;
  147.     event->szMessage = strdup(szMessage);
  148.     event->bConfirm = bConfirm;
  149.     PR_InitEvent(&event->ce.event, context,
  150.          (PRHandleEventProc)et_HandleEvent_MessageBox,
  151.          (PRDestroyEventProc)et_DestroyEvent_MessageBox);
  152.     ok = (JSBool) et_PostEvent(&event->ce, TRUE);
  153.  
  154.     return(ok);
  155.  
  156. }
  157.  
  158. /****************************************************************************/
  159.  
  160. typedef struct {
  161.     ETEvent        ce;
  162.     const char   * szMessage;    /* progress message */
  163. } MozillaEvent_Progress;
  164.  
  165.  
  166. PR_STATIC_CALLBACK(void)
  167. et_HandleEvent_Progress(MozillaEvent_Progress* e)
  168. {
  169.     FE_Progress(e->ce.context, e->szMessage);
  170. }
  171.  
  172. PR_STATIC_CALLBACK(void)
  173. et_DestroyEvent_Progress(MozillaEvent_MessageBox* event)
  174. {
  175.     XP_FREE((char*)event->szMessage);
  176.     XP_FREE(event);
  177. }
  178.  
  179. void
  180. ET_PostProgress(MWContext* context, const char* szMessage)
  181. {
  182.     MozillaEvent_Progress* event = PR_NEW(MozillaEvent_Progress);
  183.     if (event == NULL) 
  184.         return;
  185.     PR_InitEvent(&event->ce.event, context,
  186.          (PRHandleEventProc)et_HandleEvent_Progress,
  187.          (PRDestroyEventProc)et_DestroyEvent_Progress);
  188.     event->ce.context = context;
  189.     if(szMessage)
  190.         event->szMessage = strdup(szMessage);
  191.     else
  192.         event->szMessage = NULL;
  193.     et_PostEvent(&event->ce, FALSE);
  194.  
  195. }
  196.  
  197. /****************************************************************************/
  198.  
  199. typedef struct {
  200.     ETEvent        ce;
  201.     void          * pStuff;    
  202. } MozillaEvent_Void;
  203.  
  204.  
  205. PR_STATIC_CALLBACK(void)
  206. et_HandleEvent_ClearTimeout(MozillaEvent_Void* e)
  207. {
  208.     FE_ClearTimeout(e->pStuff);
  209. }
  210.  
  211. void
  212. ET_PostClearTimeout(void * pStuff)
  213. {
  214.     MozillaEvent_Void* event = PR_NEW(MozillaEvent_Void);
  215.     if (event == NULL) 
  216.         return;
  217.     PR_InitEvent(&event->ce.event, NULL,
  218.          (PRHandleEventProc)et_HandleEvent_ClearTimeout,
  219.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  220.     event->ce.context = NULL;
  221.     event->pStuff = pStuff;
  222.     et_PostEvent(&event->ce, FALSE);
  223.  
  224. }
  225.  
  226. /****************************************************************************/
  227.  
  228. /*
  229.  * OK, timeouts are messy.  We are in a separate thread, we want to
  230.  *   call the mozilla thread to fire a timeout.  When the timeout
  231.  *   fires we need to get a message sent back to our thread to call
  232.  *   our timeout since, presumably, our timeout needs to run in our
  233.  *   thread and not the mozilla thread.
  234.  * Make a duplicate of the current event structure in case the 
  235.  *   timeout gets fired and the 'run the closure' event gets sent
  236.  *   before we have returned from PR_PostSynchronousEvent().
  237.  */
  238. PR_STATIC_CALLBACK(void*)
  239. et_HandleEvent_SetTimeout(MozillaEvent_Timeout* e)
  240. {
  241.     MozillaEvent_Timeout* event = XP_NEW_ZAP(MozillaEvent_Timeout);
  242.     if (event == NULL) 
  243.         return(NULL);
  244.  
  245.     event->fnCallback = e->fnCallback;
  246.     event->pClosure = e->pClosure;
  247.     event->ulTime = e->ulTime;
  248.     event->ce.doc_id = e->ce.doc_id;
  249.     event->pTimerId = FE_SetTimeout(ET_FireTimeoutCallBack, event, e->ulTime);
  250.     
  251.     return(event->pTimerId);
  252. }
  253.  
  254. void *
  255. ET_PostSetTimeout(TimeoutCallbackFunction fnCallback, void * pClosure, 
  256.                   uint32 ulTime, int32 doc_id)
  257. {
  258.     MozillaEvent_Timeout* event = XP_NEW_ZAP(MozillaEvent_Timeout);
  259.     void * ret;
  260.     if (event == NULL) 
  261.         return(NULL);
  262.     PR_InitEvent(&event->ce.event, NULL,
  263.          (PRHandleEventProc)et_HandleEvent_SetTimeout,
  264.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  265.     event->ce.doc_id = doc_id;
  266.     event->fnCallback = fnCallback;
  267.     event->pClosure = pClosure;
  268.     event->ulTime = ulTime;
  269.  
  270.     ret = et_PostEvent(&event->ce, TRUE);
  271.     return(ret);
  272.  
  273. }
  274.  
  275. typedef struct {
  276.     ETEvent        ce;
  277.     int32           wrap_width;
  278.     int32           parent_layer_id;
  279. } MozillaEvent_CreateLayer;
  280.  
  281. PR_STATIC_CALLBACK(void*)
  282. et_HandleEvent_CreateLayer(MozillaEvent_CreateLayer * e)
  283. {
  284.     int32 layer_id;
  285.  
  286.     /* See if the document has changed since this event was sent. */
  287.     if(e->ce.doc_id != XP_DOCID(e->ce.context))
  288.     return NULL;
  289.  
  290.     layer_id = LO_CreateNewLayer(e->ce.context, e->wrap_width, e->parent_layer_id);
  291.     return (void*)layer_id;
  292. }
  293.  
  294. int32
  295. ET_PostCreateLayer(MWContext *context, int32 wrap_width, int32 parent_layer_id)
  296. {
  297.     int32 ret;
  298.     MozillaEvent_CreateLayer * event = XP_NEW_ZAP(MozillaEvent_CreateLayer);
  299.     if (event == NULL) 
  300.         return(0);
  301.     PR_InitEvent(&event->ce.event, NULL,
  302.          (PRHandleEventProc)et_HandleEvent_CreateLayer,
  303.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  304.     event->ce.context = context;
  305.     event->ce.doc_id = XP_DOCID(context);
  306.     event->wrap_width = wrap_width;
  307.     event->parent_layer_id = parent_layer_id;
  308.  
  309.     ret = (int32)et_PostEvent(&event->ce, TRUE);
  310.     return(ret);
  311. }
  312.  
  313. /****************************************************************************/
  314.  
  315. PR_STATIC_CALLBACK(void)
  316. et_HandleEvent_DestroyWindow(ETEvent* e)
  317. {
  318.     e->context->waitingMode = FALSE;
  319.     FE_DestroyWindow(e->context);
  320. }
  321.  
  322. void
  323. ET_PostDestroyWindow(MWContext * context)
  324. {
  325.     ETEvent * event = PR_NEW(ETEvent);
  326.     if (event == NULL) 
  327.         return;
  328.     PR_InitEvent(&event->event, context,
  329.          (PRHandleEventProc)et_HandleEvent_DestroyWindow,
  330.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  331.     event->context = context;
  332.     et_PostEvent(event, FALSE);
  333.  
  334. }
  335.  
  336. /****************************************************************************/
  337.  
  338. typedef struct {
  339.     ETEvent          ce;
  340.     LO_Element      * pForm;
  341.     int32             action;
  342.     int32              docID;
  343.     PRPackedBool      duplicate;
  344. } MozillaEvent_ManipulateForm;
  345.  
  346.  
  347. PR_STATIC_CALLBACK(void)
  348. et_HandleEvent_ManipulateForm(MozillaEvent_ManipulateForm* e)
  349. {
  350.  
  351.     /* see if the document has changed since this event was sent */
  352.     if(e->docID != XP_DOCID(e->ce.context))
  353.     return;
  354.  
  355.     switch(e->action) {
  356.     case EVENT_BLUR:
  357.         FE_BlurInputElement(e->ce.context, e->pForm);
  358.         break;
  359.     case EVENT_FOCUS:
  360.         FE_FocusInputElement(e->ce.context, e->pForm);
  361.         break;
  362.     case EVENT_SELECT:
  363.         FE_SelectInputElement(e->ce.context, e->pForm);
  364.         break;
  365.     case EVENT_CLICK:
  366.         FE_ClickInputElement(e->ce.context, e->pForm);
  367.         break;
  368.     case EVENT_CHANGE:
  369.         FE_ChangeInputElement(e->ce.context, e->pForm);
  370.         break;
  371.     default:
  372.         XP_ASSERT(0);
  373.     }
  374. }
  375.  
  376. PR_STATIC_CALLBACK(void)
  377. et_check_already_pending(MozillaEvent_ManipulateForm* event, 
  378.              MozillaEvent_ManipulateForm* data, 
  379.              PREventQueue* queue)
  380. {
  381.     if (event->ce.event.owner == data->ce.event.owner) {
  382.     if (event->action == data->action)
  383.         data->duplicate = TRUE;
  384.     }
  385. }
  386.  
  387. void
  388. ET_PostManipulateForm(MWContext * context, LO_Element * pForm, int32 action)
  389. {
  390.     MozillaEvent_ManipulateForm* event;
  391.  
  392.     event = PR_NEW(MozillaEvent_ManipulateForm);
  393.     if (event == NULL) 
  394.         return;
  395.  
  396.     PR_InitEvent(&event->ce.event, pForm,
  397.          (PRHandleEventProc)et_HandleEvent_ManipulateForm,
  398.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  399.     event->ce.context = context;
  400.     event->docID = XP_DOCID(context);
  401.     event->pForm = pForm;
  402.     event->action = action;
  403.     event->duplicate = FALSE;
  404.  
  405.     /*
  406.      * Now that we have built the event use it to see if a similar
  407.      *   event already exists.  If one does, the owner field will
  408.      *   get cleared in the event we just created
  409.      */
  410.     PR_MapEvents(mozilla_event_queue, 
  411.          (PREventFunProc)et_check_already_pending, 
  412.          event);
  413.     if (event->duplicate) {
  414.     XP_FREE(event);
  415.     return;
  416.     }
  417.  
  418.     et_PostEvent(&event->ce, FALSE);
  419.  
  420. }
  421.  
  422. /****************************************************************************/
  423.  
  424. PR_STATIC_CALLBACK(void)
  425. et_HandleEvent_ClearView(ETEvent * e)
  426. {
  427.     FE_ClearView(e->context, FE_VIEW);
  428. }
  429.  
  430. void
  431. ET_PostClearView(MWContext * context)
  432. {
  433.     ETEvent * event = PR_NEW(ETEvent);
  434.     if (event == NULL) 
  435.         return;
  436.     PR_InitEvent(&event->event, context,
  437.          (PRHandleEventProc)et_HandleEvent_ClearView,
  438.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  439.     event->context = context;
  440.     et_PostEvent(event, FALSE);
  441.  
  442. }
  443.  
  444. /****************************************************************************/
  445.  
  446. PR_STATIC_CALLBACK(void)
  447. et_HandleEvent_FreeImageElement(MozillaEvent_Void* e)
  448. {
  449.     LO_ImageStruct *lo_image = (LO_ImageStruct *) e->pStuff;
  450.  
  451.     IL_DestroyImage(lo_image->image_req);
  452.     lo_image->image_req = NULL;
  453. }
  454.  
  455. /*
  456.  * From the code flow it looked like some people were depending
  457.  *   on this getting done before continuing.  Not sure if that
  458.  *   is really the case or not.  Do we need to be synchronous?
  459.  */
  460. void
  461. ET_PostFreeImageElement(MWContext * context, void * pStuff)
  462. {
  463.     MozillaEvent_Void* event = PR_NEW(MozillaEvent_Void);
  464.     if (event == NULL) 
  465.         return;
  466.     PR_InitEvent(&event->ce.event, context,
  467.          (PRHandleEventProc)et_HandleEvent_FreeImageElement,
  468.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  469.     event->ce.context = context;
  470.     event->pStuff = pStuff;
  471.  
  472.     et_PostEvent(&event->ce, TRUE);
  473.  
  474. }
  475.  
  476. /****************************************************************************/
  477.  
  478. /* Free all images in the mocha image context. */
  479. PR_STATIC_CALLBACK(void)
  480. et_HandleEvent_FreeAnonImages(MozillaEvent_Void* e)
  481. {
  482.     IL_DestroyImageGroup((IL_GroupContext *)e->pStuff);
  483. }
  484.  
  485. void
  486. ET_PostFreeAnonImages(MWContext *context, IL_GroupContext *img_cx)
  487. {
  488.     MozillaEvent_Void* event = PR_NEW(MozillaEvent_Void);
  489.     if (event == NULL) 
  490.         return;
  491.     PR_InitEvent(&event->ce.event, context,
  492.          (PRHandleEventProc)et_HandleEvent_FreeAnonImages,
  493.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  494.     event->ce.context = context;
  495.     event->pStuff = img_cx;
  496.  
  497.     et_PostEvent(&event->ce, FALSE);
  498. }
  499.  
  500. /****************************************************************************/
  501.  
  502. /* 
  503.  * Destroy the mocha image context in the Mozilla thread since 
  504.  *   its destruction must succeed the actual destruction of 
  505.  *   anonymous images. 
  506.  */
  507. PR_STATIC_CALLBACK(void)
  508. et_HandleEvent_FreeImageContext(MozillaEvent_Void* e)
  509. {
  510.     IL_DestroyGroupContext((IL_GroupContext *)e->pStuff);
  511. }
  512.  
  513. void
  514. ET_PostFreeImageContext(MWContext *context, IL_GroupContext *img_cx)
  515. {
  516.     MozillaEvent_Void* event = PR_NEW(MozillaEvent_Void);
  517.     if (event == NULL) 
  518.         return;
  519.     PR_InitEvent(&event->ce.event, context,
  520.          (PRHandleEventProc)et_HandleEvent_FreeImageContext,
  521.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  522.     event->ce.context = context;
  523.     event->pStuff = img_cx;
  524.  
  525.     et_PostEvent(&event->ce, FALSE);
  526. }
  527.  
  528. /****************************************************************************/
  529.  
  530. PR_STATIC_CALLBACK(void)
  531. et_HandleEvent_GetUrl(MozillaEvent_Void* e)
  532. {
  533.     FE_GetURL(e->ce.context, (URL_Struct *) e->pStuff);
  534. }
  535.  
  536. void
  537. ET_PostGetUrl(MWContext * context, URL_Struct * pUrl)
  538. {
  539.     MozillaEvent_Void* event = PR_NEW(MozillaEvent_Void);
  540.     if (event == NULL) 
  541.         return;
  542.     PR_InitEvent(&event->ce.event, context,
  543.          (PRHandleEventProc)et_HandleEvent_GetUrl,
  544.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  545.     event->ce.context = context;
  546.     event->pStuff = pUrl;
  547.     et_PostEvent(&event->ce, FALSE);
  548.  
  549. }
  550.  
  551. /****************************************************************************/
  552.  
  553. typedef struct {
  554.     ETEvent        ce;
  555.     char*        szMessage;    /* message for dialog */
  556.     char*           szDefault;
  557. } MozillaEvent_Prompt;
  558.  
  559.  
  560. PR_STATIC_CALLBACK(void *)
  561. et_HandleEvent_Prompt(MozillaEvent_Prompt* e)
  562. {
  563.     void *pRet;
  564.     Bool bPriorJSCalling = FALSE;
  565.     if( e->ce.context ) {
  566.         bPriorJSCalling = e->ce.context->bJavaScriptCalling;
  567.         e->ce.context->bJavaScriptCalling = TRUE;
  568.     }
  569.     
  570.     pRet = (void *)FE_Prompt(e->ce.context, e->szMessage, e->szDefault);
  571.     
  572.     if( e->ce.context ) 
  573.         e->ce.context->bJavaScriptCalling = bPriorJSCalling;
  574.             
  575.     return pRet;
  576. }
  577.  
  578. PR_STATIC_CALLBACK(void)
  579. et_DestroyEvent_Prompt(MozillaEvent_Prompt* event)
  580. {
  581.     XP_FREE((char*)event->szMessage);
  582.     XP_FREE((char*)event->szDefault);
  583.     XP_FREE(event);
  584. }
  585.  
  586. char *
  587. ET_PostPrompt(MWContext* context, const char* szMessage, const char * szDefault)
  588. {
  589.     char * ret;
  590.     MozillaEvent_Prompt* event = PR_NEW(MozillaEvent_Prompt);
  591.     if (event == NULL) 
  592.         return(NULL);
  593.     PR_InitEvent(&event->ce.event, context,
  594.          (PRHandleEventProc)et_HandleEvent_Prompt,
  595.          (PRDestroyEventProc)et_DestroyEvent_Prompt);
  596.     event->ce.context = context;
  597.     event->szMessage = strdup(szMessage);
  598.     if(szDefault)
  599.         event->szDefault = strdup(szDefault);
  600.     else
  601.         event->szDefault = NULL;
  602.  
  603.     ret = (char *) et_PostEvent(&event->ce, TRUE);
  604.     return(ret);
  605.  
  606. }
  607.  
  608. /****************************************************************************/
  609.  
  610. typedef struct {
  611.     ETEvent          ce;
  612.     URL_Struct      * pUrl;
  613.     char            * szName;
  614.     Chrome          * pChrome;
  615. } MozillaEvent_NewWindow;
  616.  
  617.  
  618. PR_STATIC_CALLBACK(void*)
  619. et_HandleEvent_NewWindow(MozillaEvent_NewWindow* e)
  620. {
  621.     return((void *)FE_MakeNewWindow(e->ce.context, e->pUrl, e->szName, 
  622.                                     e->pChrome));
  623. }
  624.  
  625. PR_STATIC_CALLBACK(void)
  626. et_DestroyEvent_NewWindow(MozillaEvent_NewWindow* event)
  627. {
  628.     NET_DropURLStruct(event->pUrl);
  629.     if (event->szName)
  630.     XP_FREE((char*)event->szName);
  631.     XP_FREE(event);
  632. }
  633.  
  634. MWContext *
  635. ET_PostNewWindow(MWContext* context, URL_Struct * pUrl, 
  636.                  char * szName, Chrome * pChrome)
  637. {
  638.     MWContext * ret;
  639.     MozillaEvent_NewWindow* event = PR_NEW(MozillaEvent_NewWindow);
  640.     if (event == NULL) 
  641.         return(NULL);
  642.     PR_InitEvent(&event->ce.event, context,
  643.          (PRHandleEventProc)et_HandleEvent_NewWindow,
  644.          (PRDestroyEventProc)et_DestroyEvent_NewWindow);
  645.     event->ce.context = context;
  646.     event->pUrl = NET_HoldURLStruct(pUrl);
  647.     if(szName)
  648.     event->szName = strdup(szName);
  649.     else
  650.     event->szName = NULL;
  651.     event->pChrome = pChrome;
  652.  
  653.     ret = (MWContext *) et_PostEvent(&event->ce, TRUE);
  654.     return(ret);
  655.  
  656. }
  657.  
  658. /****************************************************************************/
  659.  
  660. typedef struct {
  661.     ETEvent          ce;
  662.     Chrome          * pChrome;
  663. } MozillaEvent_UpdateWindow;
  664.  
  665.  
  666. PR_STATIC_CALLBACK(void)
  667. et_HandleEvent_UpdateWindow(MozillaEvent_UpdateWindow* e)
  668. {
  669.     FE_UpdateChrome(e->ce.context, e->pChrome);
  670. }
  671.  
  672. void
  673. ET_PostUpdateChrome(MWContext* context, Chrome * pChrome)
  674. {
  675.     MozillaEvent_UpdateWindow* event = PR_NEW(MozillaEvent_UpdateWindow);
  676.     if (event == NULL) 
  677.         return;
  678.     PR_InitEvent(&event->ce.event, context,
  679.          (PRHandleEventProc)et_HandleEvent_UpdateWindow,
  680.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  681.     event->ce.context = context;
  682.     event->pChrome = pChrome;
  683.  
  684.     et_PostEvent(&event->ce, TRUE);
  685.  
  686. }
  687.  
  688. /****************************************************************************/
  689.  
  690. typedef struct {
  691.     ETEvent          ce;
  692.     Chrome          * pChrome;
  693. } MozillaEvent_QueryWindow;
  694.  
  695.  
  696. PR_STATIC_CALLBACK(void)
  697. et_HandleEvent_QueryWindow(MozillaEvent_QueryWindow* e)
  698. {
  699.     FE_QueryChrome(e->ce.context, e->pChrome);
  700. }
  701.  
  702. void
  703. ET_PostQueryChrome(MWContext* context, Chrome * pChrome)
  704. {
  705.     MozillaEvent_QueryWindow* event = PR_NEW(MozillaEvent_QueryWindow);
  706.     if (event == NULL) 
  707.         return;
  708.     PR_InitEvent(&event->ce.event, context,
  709.          (PRHandleEventProc)et_HandleEvent_QueryWindow,
  710.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  711.     event->ce.context = context;
  712.     event->pChrome = pChrome;
  713.  
  714.     et_PostEvent(&event->ce, TRUE);
  715.  
  716. }
  717.  
  718. /****************************************************************************/
  719.  
  720. typedef struct {
  721.     ETEvent          ce;
  722.     int32         *pPixel;
  723.     int32         *pPallette;
  724. } MozillaEvent_GetColorDepth;
  725.  
  726.  
  727. PR_STATIC_CALLBACK(void)
  728. et_HandleEvent_GetColorDepth(MozillaEvent_GetColorDepth* e)
  729. {
  730.     FE_GetPixelAndColorDepth(e->ce.context, e->pPixel, e->pPallette);
  731. }
  732.  
  733. void
  734. ET_PostGetColorDepth(MWContext* context, int32 *pPixel, int32 *pPallette)
  735. {
  736.     int32 *pMPixel = NULL, *pMPallette = NULL;
  737.     
  738.     MozillaEvent_GetColorDepth* event = PR_NEW(MozillaEvent_GetColorDepth);
  739.     if (event == NULL) 
  740.         return;
  741.  
  742.     pMPixel = XP_ALLOC(sizeof(int32));
  743.     if (pMPixel == NULL)
  744.     goto fail;
  745.  
  746.     pMPallette = XP_ALLOC(sizeof(int32));
  747.     if (pMPallette == NULL)
  748.     goto fail;
  749.  
  750.     PR_InitEvent(&event->ce.event, context,
  751.          (PRHandleEventProc)et_HandleEvent_GetColorDepth,
  752.          (PRDestroyEventProc)et_DestroyEvent_WaitForIt);
  753.     event->ce.context = context;
  754.     event->pPixel = pMPixel;
  755.     event->pPallette = pMPallette;
  756.  
  757.     et_PostEvent(&event->ce, TRUE);
  758.     *pPixel = *event->pPixel;
  759.     *pPallette = *event->pPallette;
  760.  
  761. fail:
  762.     if (pMPixel)
  763.     XP_FREE(pMPixel);
  764.     if (pMPallette)
  765.     XP_FREE(pMPallette);
  766.     if (event)
  767.     XP_FREE(event);
  768. }
  769.  
  770. /****************************************************************************/
  771.  
  772. typedef struct {
  773.     ETEvent          ce;
  774.     int32         *pX;
  775.     int32         *pY;
  776. } MozillaEvent_GetScreenSize;
  777.  
  778.  
  779. PR_STATIC_CALLBACK(void)
  780. et_HandleEvent_GetScreenSize(MozillaEvent_GetScreenSize* e)
  781. {
  782.     FE_GetScreenSize(e->ce.context, e->pX, e->pY);
  783. }
  784.  
  785. void
  786. ET_PostGetScreenSize(MWContext* context, int32 *pX, int32 *pY)
  787. {
  788.     int32 *pMX = NULL, *pMY = NULL;
  789.     
  790.     MozillaEvent_GetScreenSize* event = PR_NEW(MozillaEvent_GetScreenSize);
  791.     if (event == NULL) 
  792.         return;
  793.  
  794.     pMX = XP_ALLOC(sizeof(int32));
  795.     if (pMX == NULL)
  796.     goto fail;
  797.  
  798.     pMY = XP_ALLOC(sizeof(int32));
  799.     if (pMY == NULL)
  800.     goto fail;
  801.  
  802.     PR_InitEvent(&event->ce.event, context,
  803.          (PRHandleEventProc)et_HandleEvent_GetScreenSize,
  804.          (PRDestroyEventProc)et_DestroyEvent_WaitForIt);
  805.     event->ce.context = context;
  806.     event->pX = pMX;
  807.     event->pY = pMY;
  808.  
  809.     et_PostEvent(&event->ce, TRUE);
  810.     *pX = *event->pX;
  811.     *pY = *event->pY;
  812.  
  813. fail:
  814.     if (pMX)
  815.     XP_FREE(pMX);
  816.     if (pMY)
  817.     XP_FREE(pMY);
  818.     if (event)
  819.     XP_FREE(event);
  820. }
  821.  
  822. /****************************************************************************/
  823.  
  824. typedef struct {
  825.     ETEvent          ce;
  826.     int32         *pX;
  827.     int32         *pY;
  828.     int32         *pLeft;
  829.     int32         *pTop;
  830. } MozillaEvent_GetAvailScreenRect;
  831.  
  832.  
  833. PR_STATIC_CALLBACK(void)
  834. et_HandleEvent_GetAvailScreenRect(MozillaEvent_GetAvailScreenRect* e)
  835. {
  836.     FE_GetAvailScreenRect(e->ce.context, e->pX, e->pY, e->pLeft, e->pTop);
  837. }
  838.  
  839. void
  840. ET_PostGetAvailScreenRect(MWContext* context, int32 *pX, int32 *pY, int32 *pLeft, 
  841.                                     int32 *pTop)
  842. {
  843.     int32 *pMX = NULL, *pMY = NULL, *pMLeft = NULL, *pMTop = NULL;
  844.     
  845.     MozillaEvent_GetAvailScreenRect* event = PR_NEW(MozillaEvent_GetAvailScreenRect);
  846.     if (event == NULL) 
  847.         return;
  848.  
  849.     pMX = XP_ALLOC(sizeof(int32));
  850.     if (pMX == NULL)
  851.     goto fail;
  852.     pMY = XP_ALLOC(sizeof(int32));
  853.     if (pMY == NULL)
  854.     goto fail;
  855.     pMLeft = XP_ALLOC(sizeof(int32));
  856.     if (pMLeft == NULL)
  857.     goto fail;
  858.     pMTop = XP_ALLOC(sizeof(int32));
  859.     if (pMTop == NULL)
  860.     goto fail;
  861.  
  862.  
  863.     PR_InitEvent(&event->ce.event, context,
  864.          (PRHandleEventProc)et_HandleEvent_GetAvailScreenRect,
  865.          (PRDestroyEventProc)et_DestroyEvent_WaitForIt);
  866.     event->ce.context = context;
  867.     event->pX = pMX;
  868.     event->pY = pMY;
  869.     event->pLeft = pMLeft;
  870.     event->pTop = pMTop;
  871.  
  872.     et_PostEvent(&event->ce, TRUE);
  873.     *pX = *event->pX;
  874.     *pY = *event->pY;
  875.     *pLeft = *event->pLeft;
  876.     *pTop = *event->pTop;
  877.  
  878. fail:
  879.     if (pMX)
  880.     XP_FREE(pMX);
  881.     if (pMY)
  882.     XP_FREE(pMY);
  883.     if (pMLeft)
  884.     XP_FREE(pMLeft);
  885.     if (pMTop)
  886.     XP_FREE(pMTop);
  887.     if (event)
  888.     XP_FREE(event);
  889. }
  890.  
  891. /****************************************************************************/
  892.  
  893. typedef struct {
  894.     ETEvent          ce;
  895.     char            * szText;
  896. } MozillaEvent_GetSelectedText;
  897.  
  898.  
  899. PR_STATIC_CALLBACK(void*)
  900. et_HandleEvent_GetSelectedText(MozillaEvent_GetSelectedText* e)
  901. {
  902.     char * rv;
  903.  
  904.     rv = (char *)LO_GetSelectionText(e->ce.context);
  905.  
  906.     if (rv)
  907.     rv = XP_STRDUP(rv);
  908.  
  909.     return rv;
  910. }
  911.  
  912. char *
  913. ET_PostGetSelectedText(MWContext* context)
  914. {
  915.     char * ret;
  916.     MozillaEvent_GetSelectedText* event = XP_NEW_ZAP(MozillaEvent_GetSelectedText);
  917.     if (event == NULL) 
  918.         return(NULL);
  919.     PR_InitEvent(&event->ce.event, context,
  920.          (PRHandleEventProc)et_HandleEvent_GetSelectedText,
  921.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  922.     event->ce.context = context;
  923.  
  924.     ret = (char *) et_PostEvent(&event->ce, TRUE);
  925.  
  926.     return(ret);
  927.  
  928. }
  929.  
  930. /****************************************************************************/
  931.  
  932. typedef struct {
  933.     ETEvent          ce;
  934.     int               location;
  935.     int32             x, y;
  936. } MozillaEvent_ScrollTo;
  937.  
  938.  
  939. PR_STATIC_CALLBACK(void)
  940. et_HandleEvent_ScrollTo(MozillaEvent_ScrollTo* e)
  941. {
  942.     FE_ScrollDocTo(e->ce.context, e->location, e->x, e->y);    
  943. }
  944.  
  945. void
  946. ET_PostScrollDocTo(MWContext* context, int loc, int32 x, int32 y)
  947. {
  948.     MozillaEvent_ScrollTo* event = PR_NEW(MozillaEvent_ScrollTo);
  949.     if (event == NULL) 
  950.         return;
  951.     PR_InitEvent(&event->ce.event, context,
  952.          (PRHandleEventProc)et_HandleEvent_ScrollTo,
  953.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  954.     event->ce.context = context;
  955.     event->location = loc;
  956.     event->x = x;
  957.     event->y = y;
  958.  
  959.     et_PostEvent(&event->ce, FALSE);
  960.  
  961. }
  962.  
  963. /****************************************************************************/
  964.  
  965. typedef struct {
  966.     ETEvent          ce;
  967.     int               location;
  968.     int32             x, y;
  969. } MozillaEvent_ScrollBy;
  970.  
  971.  
  972. PR_STATIC_CALLBACK(void)
  973. et_HandleEvent_ScrollBy(MozillaEvent_ScrollBy* e)
  974. {
  975.     FE_ScrollDocBy(e->ce.context, e->location, e->x, e->y);    
  976. }
  977.  
  978. void
  979. ET_PostScrollDocBy(MWContext* context, int loc, int32 x, int32 y)
  980. {
  981.     MozillaEvent_ScrollBy* event = PR_NEW(MozillaEvent_ScrollBy);
  982.     if (event == NULL) 
  983.         return;
  984.     PR_InitEvent(&event->ce.event, context,
  985.          (PRHandleEventProc)et_HandleEvent_ScrollBy,
  986.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  987.     event->ce.context = context;
  988.     event->location = loc;
  989.     event->x = x;
  990.     event->y = y;
  991.  
  992.     et_PostEvent(&event->ce, FALSE);
  993.  
  994. }
  995.  
  996.  
  997. /****************************************************************************/
  998.  
  999. PR_STATIC_CALLBACK(void)
  1000. et_HandleEvent_BackCommand(ETEvent* e)
  1001. {
  1002.     FE_BackCommand(e->context);    
  1003. }
  1004.  
  1005. void
  1006. ET_PostBackCommand(MWContext* context)
  1007. {
  1008.     ETEvent* event = PR_NEW(ETEvent);
  1009.     if (event == NULL) 
  1010.         return;
  1011.     PR_InitEvent(&event->event, context,
  1012.          (PRHandleEventProc)et_HandleEvent_BackCommand,
  1013.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1014.     event->context = context;
  1015.  
  1016.     et_PostEvent(event, FALSE);
  1017.  
  1018. }
  1019.  
  1020. /****************************************************************************/
  1021.  
  1022. typedef struct {
  1023.     ETEvent          ce;
  1024. } MozillaEvent_ForwardCommand;
  1025.  
  1026.  
  1027. PR_STATIC_CALLBACK(void)
  1028. et_HandleEvent_ForwardCommand(ETEvent* e)
  1029. {
  1030.     FE_ForwardCommand(e->context);    
  1031. }
  1032.  
  1033. void
  1034. ET_PostForwardCommand(MWContext* context)
  1035. {
  1036.     ETEvent* event = PR_NEW(ETEvent);
  1037.     if (event == NULL) 
  1038.         return;
  1039.     PR_InitEvent(&event->event, context,
  1040.          (PRHandleEventProc)et_HandleEvent_ForwardCommand,
  1041.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1042.     event->context = context;
  1043.  
  1044.     et_PostEvent(event, FALSE);
  1045.  
  1046. }
  1047.  
  1048. /****************************************************************************/
  1049.  
  1050. PR_STATIC_CALLBACK(void)
  1051. et_HandleEvent_HomeCommand(ETEvent* e)
  1052. {
  1053.     FE_HomeCommand(e->context);    
  1054. }
  1055.  
  1056. void
  1057. ET_PostHomeCommand(MWContext* context)
  1058. {
  1059.     ETEvent* event = PR_NEW(ETEvent);
  1060.     if (event == NULL) 
  1061.         return;
  1062.     PR_InitEvent(&event->event, context,
  1063.          (PRHandleEventProc)et_HandleEvent_HomeCommand,
  1064.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1065.     event->context = context;
  1066.  
  1067.     et_PostEvent(event, FALSE);
  1068.  
  1069. }
  1070.  
  1071. /****************************************************************************/
  1072.  
  1073. typedef struct {
  1074.     ETEvent          ce;
  1075.     char *          szName;
  1076.     XP_Bool          matchCase;
  1077.     XP_Bool          searchBackward;
  1078. } MozillaEvent_FindCommand;
  1079.  
  1080.  
  1081. PR_STATIC_CALLBACK(void*)
  1082. et_HandleEvent_FindCommand(MozillaEvent_FindCommand* e)
  1083. {
  1084.     return(void *)FE_FindCommand(e->ce.context, e->szName, e->matchCase, e->searchBackward, FALSE);    
  1085. }
  1086.  
  1087. PR_STATIC_CALLBACK(void)
  1088. et_DestroyEvent_FindCommand(MozillaEvent_FindCommand* event)
  1089. {
  1090.     if(event->szName)
  1091.     XP_FREE((char*)event->szName);
  1092.     XP_FREE(event);
  1093. }
  1094.  
  1095. JSBool
  1096. ET_PostFindCommand(MWContext* context, char *szName, JSBool matchCase,
  1097.            JSBool searchBackward)
  1098. {
  1099.     JSBool ret;
  1100.     
  1101.     MozillaEvent_FindCommand* event = PR_NEW(MozillaEvent_FindCommand);
  1102.     if (event == NULL) 
  1103.         return JS_FALSE;
  1104.     PR_InitEvent(&event->ce.event, context,
  1105.          (PRHandleEventProc)et_HandleEvent_FindCommand,
  1106.          (PRDestroyEventProc)et_DestroyEvent_FindCommand);
  1107.     event->ce.context = context;
  1108.     if(szName)
  1109.     event->szName = strdup(szName);
  1110.     else
  1111.     event->szName = NULL;
  1112.     event->matchCase = (XP_Bool)matchCase;
  1113.     event->searchBackward = (XP_Bool)searchBackward;
  1114.  
  1115.     ret = (JSBool)et_PostEvent(&event->ce, TRUE);
  1116.     return(ret);
  1117.  
  1118. }
  1119.  
  1120. /****************************************************************************/
  1121.  
  1122. typedef struct {
  1123.     ETEvent          ce;
  1124. } MozillaEvent_PrintCommand;
  1125.  
  1126. PR_STATIC_CALLBACK(void)
  1127. et_HandleEvent_PrintCommand(ETEvent* e)
  1128. {
  1129.     FE_PrintCommand(e->context);    
  1130. }
  1131.  
  1132. void
  1133. ET_PostPrintCommand(MWContext* context)
  1134. {
  1135.     ETEvent* event = PR_NEW(ETEvent);
  1136.     if (event == NULL) 
  1137.         return;
  1138.     PR_InitEvent(&event->event, context,
  1139.          (PRHandleEventProc)et_HandleEvent_PrintCommand,
  1140.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1141.     event->context = context;
  1142.  
  1143.     et_PostEvent(event, FALSE);
  1144.  
  1145. }
  1146.  
  1147. /****************************************************************************/
  1148.  
  1149. PR_STATIC_CALLBACK(void)
  1150. et_HandleEvent_OpenFileCommand(ETEvent* e)
  1151. {
  1152. }
  1153.  
  1154. void
  1155. ET_PostOpenFileCommand(MWContext* context)
  1156. {
  1157.     ETEvent* event = PR_NEW(ETEvent);
  1158.     if (event == NULL) 
  1159.         return;
  1160.     PR_InitEvent(&event->event, context,
  1161.          (PRHandleEventProc)et_HandleEvent_OpenFileCommand,
  1162.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1163.     event->context = context;
  1164.  
  1165.     et_PostEvent(event, FALSE);
  1166.  
  1167. }
  1168.  
  1169. /****************************************************************************/
  1170.  
  1171. typedef struct {
  1172.     ETEvent    ce;
  1173.     char*    szMessage;    /* message for dialog */
  1174. } MozillaEvent_HtmlAlert;
  1175.  
  1176. PR_STATIC_CALLBACK(void)
  1177. et_HandleEvent_HtmlAlert(MozillaEvent_HtmlAlert* e)
  1178. {
  1179.     XP_MakeHTMLAlert(e->ce.context, e->szMessage);
  1180. }
  1181.  
  1182. PR_STATIC_CALLBACK(void)
  1183. et_DestroyEvent_HtmlAlert(MozillaEvent_HtmlAlert* event)
  1184. {
  1185.     XP_FREE((char*)event->szMessage);
  1186.     XP_FREE(event);
  1187. }
  1188.  
  1189. void
  1190. ET_MakeHTMLAlert(MWContext* context, const char* szMessage)
  1191. {
  1192.     MozillaEvent_HtmlAlert* event = PR_NEW(MozillaEvent_HtmlAlert);
  1193.     if (event == NULL) 
  1194.         return;
  1195.     PR_InitEvent(&event->ce.event, context,
  1196.          (PRHandleEventProc)et_HandleEvent_HtmlAlert,
  1197.          (PRDestroyEventProc)et_DestroyEvent_HtmlAlert);
  1198.     event->ce.context = context;
  1199.     event->szMessage = strdup(szMessage);
  1200.  
  1201.     et_PostEvent(&event->ce, FALSE);
  1202.  
  1203. }
  1204.  
  1205. /****************************************************************************/
  1206.  
  1207. typedef struct {
  1208.     ETEvent          ce;
  1209.     LO_Element      * pEle;
  1210.     int               type;
  1211.     ETClosureFunc     fnClosure;
  1212.     void            * pStuff;
  1213.     ETEventStatus     status;
  1214. } MozillaEvent_JsEventAck;
  1215.  
  1216.  
  1217. PR_STATIC_CALLBACK(void)
  1218. et_HandleEvent_JsEventAck(MozillaEvent_JsEventAck* e)
  1219. {
  1220.     /* make sure we haven't gone away somehow */
  1221.     if(e->ce.doc_id != XP_DOCID(e->ce.context))
  1222.     e->status = EVENT_PANIC;
  1223.  
  1224.     (*e->fnClosure) (e->ce.context, e->pEle, e->type, e->pStuff, e->status);
  1225. }
  1226.  
  1227. void
  1228. ET_PostJsEventAck(MWContext* context, LO_Element * pEle, int type, 
  1229.                   ETClosureFunc fnClosure, void * pStuff, 
  1230.                   ETEventStatus status)
  1231. {
  1232.     MozillaEvent_JsEventAck* event = PR_NEW(MozillaEvent_JsEventAck);
  1233.     if (event == NULL) 
  1234.         return;
  1235.     PR_InitEvent(&event->ce.event, context,
  1236.          (PRHandleEventProc)et_HandleEvent_JsEventAck,
  1237.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1238.     event->ce.context = context;
  1239.     event->ce.doc_id = XP_DOCID(context);
  1240.     event->pEle = pEle;
  1241.     event->type = type;
  1242.     event->fnClosure = fnClosure;
  1243.     event->pStuff = pStuff;
  1244.     event->status = status;
  1245.  
  1246.     et_PostEvent(&event->ce, FALSE);
  1247.  
  1248. }
  1249.  
  1250.  
  1251. /****************************************************************************/
  1252.  
  1253. #include "mkaccess.h"
  1254. #include "mkcache.h"
  1255.  
  1256. /****************************************************************************/
  1257. /****************************************************************************/
  1258.  
  1259. typedef struct {
  1260.     ETEvent          ce;
  1261.     FO_Present_Types      format;
  1262.     URL_Struct        * pUrl;
  1263.     void        * pStuff;
  1264.     uint32          ulBytes;
  1265. } MozillaEvent_GenericNetLib;
  1266.  
  1267.  
  1268. PR_STATIC_CALLBACK(void*)
  1269. et_HandleEvent_CacheConverter(MozillaEvent_GenericNetLib* e)
  1270. {
  1271.     void *retval = (void *)NET_CacheConverter(e->format, e->pStuff, e->pUrl,
  1272.                           e->ce.context);
  1273.     return retval;
  1274. }
  1275.  
  1276. PR_STATIC_CALLBACK(void)
  1277. et_DestroyEvent_NetlibWithUrl(MozillaEvent_GenericNetLib* e)
  1278. {
  1279.     NET_DropURLStruct(e->pUrl);
  1280.     XP_FREE(e);
  1281. }
  1282.  
  1283.  
  1284. NET_StreamClass    *
  1285. ET_net_CacheConverter(FO_Present_Types format, void * obj,
  1286.                       URL_Struct *pUrl, MWContext * context)
  1287. {
  1288.     NET_StreamClass * ret;
  1289.     MozillaEvent_GenericNetLib* event = PR_NEW(MozillaEvent_GenericNetLib);
  1290.     if (event == NULL) 
  1291.         return(NULL);
  1292.     PR_InitEvent(&event->ce.event, context,
  1293.          (PRHandleEventProc)et_HandleEvent_CacheConverter,
  1294.          (PRDestroyEventProc)et_DestroyEvent_NetlibWithUrl);
  1295.     event->ce.context = context;
  1296.     event->format = format;
  1297.     event->pStuff = obj;
  1298.     event->pUrl = NET_HoldURLStruct(pUrl);
  1299.  
  1300.     ret = (NET_StreamClass *) et_PostEvent(&event->ce, TRUE);
  1301.     return(ret);
  1302.  
  1303. }
  1304.  
  1305. /****************************************************************************/
  1306.  
  1307. PR_STATIC_CALLBACK(void)
  1308. et_HandleEvent_FindURLInCache(MozillaEvent_GenericNetLib* e)
  1309. {
  1310.     NET_FindURLInCache(e->pUrl, e->ce.context);
  1311. }
  1312.  
  1313. /* NOTE: as far as libmocha is concerned, we just need this routine
  1314.    to complete.  We don't care about the return value
  1315.  */
  1316. void
  1317. ET_net_FindURLInCache(URL_Struct * pUrl, MWContext * pContext)
  1318. {
  1319.     MozillaEvent_GenericNetLib* event = PR_NEW(MozillaEvent_GenericNetLib);
  1320.     if (event == NULL) 
  1321.         return;
  1322.     PR_InitEvent(&event->ce.event, pContext,
  1323.          (PRHandleEventProc)et_HandleEvent_FindURLInCache,
  1324.          (PRDestroyEventProc)et_DestroyEvent_NetlibWithUrl);
  1325.     event->ce.context = pContext;
  1326.     event->pUrl = NET_HoldURLStruct(pUrl);
  1327.  
  1328.     et_PostEvent(&event->ce, TRUE);
  1329. }
  1330.  
  1331. /****************************************************************************/
  1332.  
  1333. PR_STATIC_CALLBACK(void*)
  1334. et_HandleEvent_StreamBuilder(MozillaEvent_GenericNetLib* e)
  1335. {
  1336.     NET_StreamClass *rv;
  1337.     
  1338.     NET_SetActiveEntryBusyStatus(e->pUrl, TRUE);
  1339.     rv = NET_StreamBuilder(e->format, e->pUrl, e->ce.context);
  1340.     NET_SetActiveEntryBusyStatus(e->pUrl, FALSE);
  1341.     return((void *)rv);
  1342. }
  1343.  
  1344. NET_StreamClass    *
  1345. ET_net_StreamBuilder(FO_Present_Types format, URL_Struct *pUrl, 
  1346.              MWContext * pContext)
  1347. {
  1348.     NET_StreamClass * ret;
  1349.     MozillaEvent_GenericNetLib* event = PR_NEW(MozillaEvent_GenericNetLib);
  1350.     if (event == NULL) 
  1351.         return(NULL);
  1352.     PR_InitEvent(&event->ce.event, pContext,
  1353.          (PRHandleEventProc)et_HandleEvent_StreamBuilder,
  1354.          (PRDestroyEventProc)et_DestroyEvent_NetlibWithUrl);
  1355.     event->ce.context = pContext;
  1356.     event->format = format;
  1357.     event->pUrl = NET_HoldURLStruct(pUrl);
  1358.  
  1359.     ret = (NET_StreamClass *) et_PostEvent(&event->ce, TRUE);
  1360.     return(ret);
  1361.  
  1362. }
  1363.  
  1364. /****************************************************************************/
  1365.  
  1366. typedef struct {
  1367.     ETEvent          ce;
  1368.     NET_StreamClass    * stream;
  1369.     void        * data;
  1370.     size_t          len;
  1371.     JSBool          self_modifying;
  1372.     JSBool          processed;
  1373. } MozillaEvent_DocWrite;
  1374.  
  1375. /*
  1376.  * A lot of this should get moved out to the layout module
  1377.  * I don't think we need to bother locking layout in this function
  1378.  *   since we are running in the mozilla thread    and the mocha
  1379.  *   thread is blocked waiting for our return value.
  1380.  */
  1381. PR_STATIC_CALLBACK(void*)
  1382. et_HandleEvent_DocWrite(MozillaEvent_DocWrite* e)
  1383. {
  1384.     lo_TopState *top_state;
  1385.     int32 pre_doc_id;
  1386.     LO_Element * save_blocking = NULL;
  1387.     LO_Element * current_script = NULL;
  1388.     Bool bumped_no_newline_count = FALSE;
  1389.     uint save_overflow;
  1390.     int status;
  1391.  
  1392.     e->processed = JS_TRUE;
  1393.  
  1394.     /*
  1395.      * If the context has a doc_id of -1 it means that its being destroyed
  1396.      * If the context's doc_id has changed only process the event if the
  1397.      *   original doc_id was zero (i.e. this is the first write and it will
  1398.      *   create a new doc with a new doc_id)
  1399.      */
  1400.     pre_doc_id = XP_DOCID(e->ce.context);
  1401.     if ((e->ce.doc_id && e->ce.doc_id != pre_doc_id) || (pre_doc_id == -1)) {
  1402. #ifdef DEBUG_chouck
  1403.     XP_TRACE(("Ignoring doc.write since doc_id changed"));
  1404. #endif
  1405.     ET_DocWriteAck(e->ce.context, -1);
  1406.     return((void *) -1);
  1407.     }
  1408.  
  1409.     if (!ET_ContinueProcessing(e->ce.context)) {
  1410. #ifdef DEBUG_chouck
  1411.     XP_TRACE(("Ignoring doc.write since was interrupted"));
  1412. #endif
  1413.     ET_DocWriteAck(e->ce.context, -1);
  1414.     return((void *) -1);
  1415.     }
  1416.  
  1417.     /* make sure top_state doesn't go away while we are holding onto it */
  1418.     LO_LockLayout();
  1419.  
  1420.     top_state = lo_GetMochaTopState(e->ce.context);
  1421.  
  1422.     /* tell layout that we are writing */
  1423.     if (top_state) {
  1424.         if (top_state->input_write_level >= MAX_INPUT_WRITE_LEVEL-1) {
  1425.         LO_UnlockLayout();
  1426.         ET_DocWriteAck(e->ce.context, -1);
  1427.             return ((void *) -1); 
  1428.         }
  1429.         top_state->input_write_level++;
  1430.  
  1431.         if (top_state->doc_data) {
  1432.         /* Suppress generated line counting if self-modifying. */
  1433.         if (e->self_modifying) {
  1434.         top_state->doc_data->no_newline_count++;
  1435.         bumped_no_newline_count = TRUE;
  1436.         }
  1437.  
  1438.         /* Save the overflow counter and XXX */
  1439.         save_overflow = top_state->doc_data->overflow_depth;
  1440.         top_state->doc_data->overflow_depth = 0;
  1441.     }
  1442.     else {
  1443.         save_overflow = 0;
  1444.     }
  1445.  
  1446.     current_script = top_state->current_script;
  1447.  
  1448.         /* 
  1449.          * if we are currently blocked by a <script> tag unblock
  1450.          *   layout for this putblock since this is some of the
  1451.          *   script data coming through.  If we are blocked on
  1452.          *   something other than a script tag don't unblock, this
  1453.          *   stuff will just get shoved onto the list to be
  1454.          *   processed after we get unblocked
  1455.          */
  1456.         save_blocking = top_state->layout_blocking_element;
  1457.         if (save_blocking && save_blocking->type == LO_SCRIPT)
  1458.             top_state->layout_blocking_element = NULL;
  1459.  
  1460.     }
  1461.  
  1462.     LO_UnlockLayout();
  1463.  
  1464.     /* shove the data out */
  1465.     status = (*e->stream->put_block)(e->stream, e->data, e->len);
  1466.  
  1467.     LO_LockLayout();
  1468.  
  1469.     /* I doubt top_state could have changed but try to be safe */
  1470.     top_state = lo_GetMochaTopState(e->ce.context);
  1471.  
  1472.     /* if the doc is still around we are done so clean up */
  1473.     if (top_state) {
  1474.     /* Stop suppressing generated line counting if self-modifying. */
  1475.     if (bumped_no_newline_count) {
  1476.         XP_ASSERT(top_state->doc_data);
  1477.         top_state->doc_data->no_newline_count--;
  1478.     }
  1479.  
  1480.     if (XP_DOCID(e->ce.context) == pre_doc_id) {
  1481.         if (top_state->doc_data) {
  1482.         top_state->doc_data->overflow_depth += save_overflow;
  1483.         XP_ASSERT(top_state->doc_data->overflow_depth >= 0);
  1484.         }
  1485.         if(top_state->layout_blocking_element == NULL) {
  1486.         /* 
  1487.          * the stuff we wrote didn't block us.  continue to block
  1488.          *   on the script tag
  1489.          */
  1490.         top_state->layout_blocking_element = save_blocking;
  1491.         top_state->input_write_level--;
  1492.         ET_DocWriteAck(e->ce.context, status);
  1493.         }
  1494.         else {
  1495.         /* 
  1496.          * If we had been blocked on the script tag but now we are
  1497.          *   blocked by something else make sure we reblock on
  1498.          *   the script tag when the new thing is done
  1499.          */
  1500.         LO_CreateReblockTag(e->ce.context, current_script);
  1501.         }
  1502.     }
  1503.     else {
  1504.         /* 
  1505.          * we just created a new top_state so its input_write_level
  1506.          *   value should be OK.  Don't mess with it.
  1507.          */
  1508.         ET_DocWriteAck(e->ce.context, status);
  1509.     }
  1510.     } 
  1511.  
  1512.     LO_UnlockLayout();
  1513.  
  1514.     return((void *) status);
  1515.  
  1516. }
  1517.  
  1518. PR_STATIC_CALLBACK(void)
  1519. et_DestroyEvent_DocWrite(MozillaEvent_DocWrite* e)
  1520. {
  1521.     if (!e->processed)
  1522.     ET_DocWriteAck(e->ce.context, -1);
  1523.     XP_FREE(e);
  1524. }
  1525.  
  1526. static uint et_EventQueueDepth;    /* number of active entries on stack */
  1527. static uint et_EventQueueCount;    /* allocated entries, including inactive */
  1528.  
  1529. static QueueStackElement *
  1530. et_PushEventQueue(MWContext * context)
  1531. {
  1532.     QueueStackElement * qse;
  1533.     char name[32];
  1534.  
  1535.     /* catch script src= tags that generate themselves. */
  1536.     if (et_EventQueueDepth >= 5)
  1537.     return NULL;
  1538.  
  1539.     /* see if we've already got one */
  1540.     qse = et_TopQueue->up;
  1541.     if (!qse) {
  1542.     qse = XP_NEW_ZAP(QueueStackElement);
  1543.     if (!qse)
  1544.         return NULL;
  1545.  
  1546.     PR_snprintf(name, sizeof name, "mocha-stack-queue-%d", et_EventQueueDepth + 1);
  1547.     qse->queue  = PR_CreateEventQueue(name, lm_InterpretThread);
  1548.  
  1549.     if (!qse->queue) {
  1550.         XP_DELETE(qse);
  1551.         return NULL;
  1552.     }
  1553.  
  1554.     et_EventQueueCount++;
  1555.     qse->down = et_TopQueue;
  1556.     et_TopQueue->up = qse;
  1557.     }
  1558.     et_EventQueueDepth++;
  1559.     qse->context = context;
  1560.     qse->done = FALSE;
  1561.  
  1562.     /*
  1563.      * This should get set by our caller
  1564.      */
  1565.     qse->doc_id = -1;  
  1566.  
  1567.     et_TopQueue = qse;
  1568.     return qse;
  1569.  
  1570. }
  1571.  
  1572. static void *              
  1573. et_PopEventQueue(void)
  1574. {
  1575.     QueueStackElement * qse;
  1576.     void * ret;
  1577.     
  1578.     qse = et_TopQueue;
  1579.     ret = qse->retval;
  1580.     et_TopQueue = qse->down;
  1581.     et_EventQueueDepth--;
  1582.     if (et_EventQueueCount > 2) {
  1583.     /* free the entry we're popping */
  1584.     et_TopQueue->up = NULL;
  1585.     PR_DestroyEventQueue(qse->queue);
  1586.     XP_DELETE(qse);
  1587.     et_EventQueueCount--;
  1588.     }
  1589.     return ret;
  1590. }
  1591.  
  1592. /*
  1593.  * Send the string str over to the mozilla thread and push it through
  1594.  *   layout.  This is an asynchronous event as far as NSPR is concerned
  1595.  *   but incase str pushes up any script or style tags we will enter a
  1596.  *   sub event loop to handle reflections and evaluations generated by
  1597.  *   this write but otherwise block the mocha thread until they have 
  1598.  *   all been proceed.
  1599.  */
  1600. int
  1601. ET_lo_DoDocWrite(JSContext *cx, MWContext * context, NET_StreamClass * stream,
  1602.                  char * str, size_t len, int32 doc_id)
  1603. {
  1604.     MochaDecoder * decoder;
  1605.     MozillaEvent_DocWrite * event;
  1606.     QueueStackElement * qse;
  1607.     int ret = -1;
  1608.  
  1609.     decoder = LM_GetMochaDecoder(context);
  1610.     if (!decoder)
  1611.     return ret;
  1612.  
  1613. #ifdef XP_UNIX
  1614.     /*
  1615.      * NOTE:  we need to toss the string out if it's doc_id doesn't match
  1616.      *        the current XP_DOCID...
  1617.      *
  1618.      *        the problem could be reproduced as follows on an IRIX 6.3
  1619.      *        O2 workstation with "lots" of plugins;
  1620.      *
  1621.      *        1. load a "plain" HTML page...
  1622.      *        2. select "about:plugins" from the help menu...
  1623.      *        3. select "about:communicator" from the help menu...
  1624.      *        4. hit the "back" button quickly to move across the
  1625.      *            "about:plugins" page before it's had a chance to
  1626.      *            finish loading...
  1627.      *        5. crashes trying to execute events from the "about:plugins"
  1628.      *            page in the context of the "plain" HTML page...
  1629.      *
  1630.      * WARNING:  there seems to be a memory corruption problem somewhere
  1631.      *           in the "event" system.  Follow the same procedure I 
  1632.      *           outlined above, except instead of loading "about:plugins"
  1633.      *           from the menu, load the "aboutplg.html" source file 
  1634.      *           directly.  If you switch rapidly across this page 
  1635.      *           you will eventually see errors like "freeing free 
  1636.      *           chunk" and "passing junk pointer to realloc" in the 
  1637.      *           course of freeing ETEvents.  After a while, this will 
  1638.      *           result in a variety of random crashes due to memory 
  1639.      *           corruption errors... [ filing a new bug for this one ]
  1640.      *
  1641.      */
  1642.     if (doc_id && (doc_id != XP_DOCID(context))) {
  1643.         LM_PutMochaDecoder(decoder);
  1644.         return ret;
  1645.     }
  1646. #endif
  1647.  
  1648.     event = XP_NEW_ZAP(MozillaEvent_DocWrite);
  1649.     if (event == NULL) {
  1650.     LM_PutMochaDecoder(decoder);
  1651.         return ret;
  1652.     }
  1653.  
  1654.     qse = et_PushEventQueue(context);
  1655.     if (!qse) {
  1656.     XP_FREEIF(event);
  1657.     LM_PutMochaDecoder(decoder);
  1658.         return ret;
  1659.     }
  1660.  
  1661.     /*
  1662.      * Set the reciever doc_id to the one that gets passed in
  1663.      */
  1664.     et_TopQueue->doc_id = doc_id;
  1665.  
  1666.     PR_InitEvent(&event->ce.event, context,
  1667.          (PRHandleEventProc)et_HandleEvent_DocWrite,
  1668.          (PRDestroyEventProc)et_DestroyEvent_DocWrite);
  1669.     event->ce.context = context;
  1670.     event->ce.doc_id = doc_id;
  1671.     event->data = str;
  1672.     event->len = len;
  1673.     event->stream = stream;
  1674.     event->self_modifying = (JSBool)(cx == decoder->js_context);
  1675.  
  1676.     et_PostEvent(&event->ce, FALSE);
  1677.  
  1678.     /* spin here until we get our DocWriteAck */
  1679.     et_SubEventLoop(qse);
  1680.     ret = (int) et_PopEventQueue();
  1681.  
  1682.     /* Sample the doc_id, since we know that it's good */
  1683.     /* XXX do this in InitWindowContent only, not here and in DefineDocument */
  1684.     decoder->doc_id = XP_DOCID(context);
  1685.  
  1686.     LM_PutMochaDecoder(decoder);
  1687.  
  1688.     return ret;
  1689.  
  1690. }
  1691.  
  1692. /****************************************************************************/
  1693.  
  1694. PR_STATIC_CALLBACK(Bool)
  1695. et_HandleEvent_PrepareLayerForWriting(JSEvent* e)
  1696. {
  1697.     CL_Layer *layer;
  1698.     Bool rv;
  1699.  
  1700.     if (e->ce.doc_id != XP_DOCID(e->ce.context))
  1701.     return FALSE;
  1702.  
  1703.     LO_LockLayout();
  1704.     layer = LO_GetLayerFromId(e->ce.context, e->layer_id);
  1705.     
  1706.     /* e->data points to the referer string, or null */
  1707.     rv =  LO_PrepareLayerForWriting(e->ce.context, e->layer_id,
  1708.                     (const char *)e->data,
  1709.                                     LO_GetLayerWrapWidth(layer));
  1710.     LO_UnlockLayout();
  1711.     
  1712.     return rv;
  1713. }
  1714.  
  1715. PR_STATIC_CALLBACK(void)
  1716. et_DestroyEvent_PrepareLayerForWriting(JSEvent* e)
  1717. {
  1718.     XP_FREEIF(e->data);
  1719.     XP_FREE(e);
  1720. }
  1721.  
  1722. Bool
  1723. ET_lo_PrepareLayerForWriting(MWContext *pContext, int32 layer_id,
  1724.                  const char *referer)
  1725. {
  1726.     JSEvent      * pEvent = (JSEvent *) XP_NEW_ZAP(JSEvent);
  1727.     if(!pEvent)
  1728.         return FALSE;
  1729.  
  1730.     PR_InitEvent(&pEvent->ce.event, pContext,
  1731.                  (PRHandleEventProc)et_HandleEvent_PrepareLayerForWriting,
  1732.                  (PRDestroyEventProc)et_DestroyEvent_PrepareLayerForWriting);
  1733.  
  1734.     /* fill in the non-PR fields we care about */
  1735.     pEvent->ce.context = pContext;
  1736.     pEvent->layer_id = layer_id;
  1737.     pEvent->ce.doc_id = XP_DOCID(pContext);
  1738.     pEvent->data = referer ? XP_STRDUP(referer) : NULL;
  1739.  
  1740.     return (Bool)et_PostEvent(&pEvent->ce, TRUE);
  1741. }
  1742.  
  1743.  
  1744. /****************************************************************************/
  1745.  
  1746. typedef struct {
  1747.     ETEvent              ce;
  1748.     ETEvalAckFunc        fn;
  1749.     void               * data;
  1750.     char               * str;
  1751.     size_t               len;
  1752.     char           * wysiwyg_url;
  1753.     char           * base_href;
  1754.     Bool                 valid;
  1755. } MozillaEvent_EvalAck;
  1756.  
  1757.  
  1758. PR_STATIC_CALLBACK(void)
  1759. et_HandleEvent_EvalAck(MozillaEvent_EvalAck* e)
  1760. {
  1761.     if (e->ce.doc_id == XP_DOCID(e->ce.context)) {
  1762.     (e->fn) (e->data, e->str, e->len, e->wysiwyg_url, 
  1763.          e->base_href, e->valid);
  1764.     }
  1765.     else {
  1766. #ifdef DEBUG_chouck
  1767.     XP_TRACE(("et_HandleEvent_EvalAck failed doc_id"));
  1768. #endif
  1769.     }
  1770. }
  1771.  
  1772. void
  1773. ET_PostEvalAck(MWContext * context, int doc_id,
  1774.            void * data, char * str, size_t len,
  1775.            char * wysiwyg_url, char * base_href,
  1776.            Bool valid, ETEvalAckFunc fn)
  1777. {
  1778.  
  1779.     MozillaEvent_EvalAck* event;
  1780.     if (fn == NULL)
  1781.         return;
  1782.  
  1783.     event = XP_NEW_ZAP(MozillaEvent_EvalAck);
  1784.     if (event == NULL) 
  1785.         return;
  1786.     PR_InitEvent(&event->ce.event, NULL,
  1787.          (PRHandleEventProc)et_HandleEvent_EvalAck,
  1788.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1789.     event->ce.context = context;
  1790.     event->ce.doc_id = doc_id;
  1791.     event->data = data;
  1792.     event->str = str;
  1793.     event->len = len;
  1794.     event->valid = valid;
  1795.     event->fn = fn;
  1796.     event->wysiwyg_url = wysiwyg_url;
  1797.     event->base_href = base_href;
  1798.  
  1799.     (void) et_PostEvent(&event->ce, FALSE);
  1800.  
  1801. }
  1802.  
  1803. /****************************************************************************/
  1804.  
  1805. typedef struct {
  1806.     ETEvent              ce;
  1807.     ETRestoreAckFunc     fn;
  1808.     void               * data;
  1809.     LO_BlockInitializeStruct *param;
  1810. } MozillaEvent_RestoreAck;
  1811.  
  1812.  
  1813. PR_STATIC_CALLBACK(void)
  1814. et_HandleEvent_RestoreAck(MozillaEvent_RestoreAck* e)
  1815. {
  1816.     /* XXX Need to do a doc_id check to see if this is still valid */
  1817.     (e->fn) (e->data, e->param);
  1818. }
  1819.  
  1820. void
  1821. ET_PostRestoreAck(void * data, LO_BlockInitializeStruct *param, 
  1822.                   ETRestoreAckFunc fn)
  1823. {
  1824.  
  1825.     MozillaEvent_RestoreAck* event;
  1826.     if (fn == NULL)
  1827.         return;
  1828.  
  1829.     event = XP_NEW_ZAP(MozillaEvent_RestoreAck);
  1830.     if (event == NULL) 
  1831.         return;
  1832.     PR_InitEvent(&event->ce.event, NULL,
  1833.          (PRHandleEventProc)et_HandleEvent_RestoreAck,
  1834.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1835.     event->data = data;
  1836.     event->param = param;
  1837.     event->fn = fn;
  1838.  
  1839.     (void) et_PostEvent(&event->ce, FALSE);
  1840.  
  1841. }
  1842.  
  1843. /****************************************************************************/
  1844.  
  1845. typedef struct MozillaEvent_DiscardStruct {
  1846.     ETEvent    ce;
  1847.     JSBool    processed;
  1848. } MozillaEvent_DiscardStruct;
  1849.  
  1850. PR_STATIC_CALLBACK(void)
  1851. et_HandleEvent_DiscardDocument(MozillaEvent_DiscardStruct * e)
  1852. {
  1853.     e->processed = JS_TRUE;
  1854.     LO_DiscardDocument(e->ce.context);
  1855.     ET_DocWriteAck(e->ce.context, 0);
  1856. }
  1857.  
  1858. PR_STATIC_CALLBACK(void)
  1859. et_DestroyEvent_DiscardDocument(MozillaEvent_DiscardStruct * e)
  1860. {
  1861.     if (!e->processed)
  1862.         ET_DocWriteAck(e->ce.context, 0);
  1863. }
  1864.  
  1865. void
  1866. ET_lo_DiscardDocument(MWContext * pContext)
  1867. {
  1868.     MozillaEvent_DiscardStruct * event;
  1869.     QueueStackElement * qse;
  1870.     
  1871.     event = PR_NEW(MozillaEvent_DiscardStruct);
  1872.     if (event == NULL) 
  1873.         return;
  1874.  
  1875.     qse = et_PushEventQueue(pContext);
  1876.     if (!qse) {
  1877.     PR_DELETE(event);
  1878.     return;
  1879.     }
  1880.  
  1881.     et_TopQueue->doc_id = XP_DOCID(pContext);
  1882.  
  1883.     PR_InitEvent(&event->ce.event, pContext,
  1884.          (PRHandleEventProc)et_HandleEvent_DiscardDocument,
  1885.          (PRDestroyEventProc)et_DestroyEvent_DiscardDocument);
  1886.     event->ce.context = pContext;
  1887.  
  1888.     qse->discarding = TRUE;
  1889.     et_PostEvent(&event->ce, FALSE);
  1890.  
  1891.     /*
  1892.      * Spin here until we get a ReleaseDocument (if needed) followed by a
  1893.      * WriteAck send by our handler.
  1894.      */
  1895.     et_SubEventLoop(qse);
  1896.  
  1897.     qse->discarding = FALSE;
  1898.     et_PopEventQueue();
  1899. }
  1900.  
  1901. /****************************************************************************/
  1902.  
  1903. typedef struct {
  1904.     ETEvent              ce;
  1905.     ETVoidPtrFunc        fn;
  1906.     void               * data;
  1907. } MozillaEvent_CallFunc;
  1908.  
  1909. PR_STATIC_CALLBACK(void)
  1910. et_HandleEvent_CallFunction(MozillaEvent_CallFunc* e)
  1911. {
  1912.     (e->fn) (e->data);
  1913. }
  1914.  
  1915. void
  1916. ET_moz_CallFunction(ETVoidPtrFunc fn, void * data)
  1917. {
  1918.     MozillaEvent_CallFunc* event = PR_NEW(MozillaEvent_CallFunc);
  1919.     if (event == NULL) 
  1920.     return;
  1921.     PR_InitEvent(&event->ce.event, NULL,
  1922.          (PRHandleEventProc)et_HandleEvent_CallFunction,
  1923.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1924.     event->fn = fn;
  1925.     event->data = data;
  1926.  
  1927.     et_PostEvent(&event->ce, TRUE);
  1928. }
  1929.  
  1930. void
  1931. ET_moz_CallFunctionAsync(ETVoidPtrFunc fn, void * data)
  1932. {
  1933.     MozillaEvent_CallFunc* event = PR_NEW(MozillaEvent_CallFunc);
  1934.     if (event == NULL) 
  1935.     return;
  1936.     PR_InitEvent(&event->ce.event, NULL,
  1937.          (PRHandleEventProc)et_HandleEvent_CallFunction,
  1938.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1939.     event->fn = fn;
  1940.     event->data = data;
  1941.  
  1942.     (void) et_PostEvent(&event->ce, FALSE);
  1943. }
  1944.  
  1945. /****************************************************************************/
  1946.  
  1947. typedef struct {
  1948.     ETEvent              ce;
  1949.     ETBoolPtrFunc        fn;
  1950.     void               * data;
  1951. } MozillaEvent_CallFuncBool;
  1952.  
  1953. PR_STATIC_CALLBACK(PRBool)
  1954. et_HandleEvent_CallFunctionBool(MozillaEvent_CallFuncBool* e)
  1955. {
  1956.     return (e->fn) (e->data);
  1957. }
  1958.  
  1959. PRBool
  1960. ET_moz_CallFunctionBool(ETBoolPtrFunc fn, void * data)
  1961. {
  1962.     PRBool ret;
  1963.     MozillaEvent_CallFuncBool* event = PR_NEW(MozillaEvent_CallFuncBool);
  1964.     if (event == NULL) 
  1965.     return PR_FALSE;
  1966.     PR_InitEvent(&event->ce.event, NULL,
  1967.          (PRHandleEventProc)et_HandleEvent_CallFunctionBool,
  1968.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1969.     event->fn = fn;
  1970.     event->data = data;
  1971.  
  1972.     ret = (PRBool) et_PostEvent(&event->ce, TRUE);
  1973.     return ret;
  1974. }
  1975.  
  1976. /****************************************************************************/
  1977. typedef struct {
  1978.     ETEvent              ce;
  1979.     ETIntPtrFunc        fn;
  1980.     void               * data;
  1981. } MozillaEvent_CallFuncInt;
  1982.  
  1983. PR_STATIC_CALLBACK(int32)
  1984. et_HandleEvent_CallFunctionInt(MozillaEvent_CallFuncInt* e)
  1985. {
  1986.     return (e->fn) (e->data);
  1987. }
  1988.  
  1989. int32
  1990. ET_moz_CallFunctionInt(ETIntPtrFunc fn, void * data)
  1991. {
  1992.     PRBool ret;
  1993.     MozillaEvent_CallFuncInt* event = PR_NEW(MozillaEvent_CallFuncInt);
  1994.     if (event == NULL) 
  1995.     return PR_FALSE;
  1996.     PR_InitEvent(&event->ce.event, NULL,
  1997.          (PRHandleEventProc)et_HandleEvent_CallFunctionInt,
  1998.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  1999.     event->fn = fn;
  2000.     event->data = data;
  2001.  
  2002.     ret = (int32) et_PostEvent(&event->ce, TRUE);
  2003.     return ret;
  2004. }
  2005.  
  2006. /****************************************************************************/
  2007.  
  2008. typedef struct {
  2009.     ETEvent              ce;
  2010.     ETStringPtrFunc        fn;
  2011.     void               * data;
  2012. } MozillaEvent_CallFuncString;
  2013.  
  2014. PR_STATIC_CALLBACK(char *)
  2015. et_HandleEvent_CallFunctionString(MozillaEvent_CallFuncString* e)
  2016. {
  2017.     return (e->fn) (e->data);
  2018. }
  2019.  
  2020. char *
  2021. ET_moz_CallFunctionString(ETStringPtrFunc fn, void * data)
  2022. {
  2023.     char * ret;
  2024.     MozillaEvent_CallFuncString* event = PR_NEW(MozillaEvent_CallFuncString);
  2025.     if (event == NULL) 
  2026.     return PR_FALSE;
  2027.     PR_InitEvent(&event->ce.event, NULL,
  2028.          (PRHandleEventProc)et_HandleEvent_CallFunctionString,
  2029.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2030.     event->fn = fn;
  2031.     event->data = data;
  2032.  
  2033.     ret = (char *) et_PostEvent(&event->ce, TRUE);
  2034.     return ret;
  2035. }
  2036.  
  2037. /****************************************************************************/
  2038.  
  2039. void
  2040. ET_moz_CallAsyncAndSubEventLoop(ETVoidPtrFunc fn, void *data,
  2041.                 MWContext *context)
  2042. {
  2043.     QueueStackElement *qse;
  2044.     
  2045.     qse = et_PushEventQueue(context);
  2046.     if ( qse == NULL ) {
  2047.     return;
  2048.     }
  2049.  
  2050.     qse->inherit_parent = JS_TRUE;
  2051.     qse->doc_id = 0;
  2052.  
  2053.     ET_moz_CallFunctionAsync(fn, data);
  2054.     
  2055.     et_SubEventLoop(qse);
  2056.     (void)et_PopEventQueue();
  2057.     return;
  2058. }
  2059.  
  2060. /****************************************************************************/
  2061. typedef struct {
  2062.     ETEvent              ce;
  2063.     MKStreamAbortFunc    fn;
  2064.     void               * data;
  2065.     int             status;
  2066. } MozillaEvent_CallAbort;
  2067.  
  2068. PR_STATIC_CALLBACK(void)
  2069. et_HandleEvent_Abort(MozillaEvent_CallAbort* e)
  2070. {
  2071.     (*e->fn)(e->data, e->status);
  2072. }
  2073.  
  2074. void
  2075. ET_moz_Abort(MKStreamAbortFunc fn, void * data, int status)
  2076. {
  2077.  
  2078.     MozillaEvent_CallAbort* event = PR_NEW(MozillaEvent_CallAbort);
  2079.     if (event == NULL) 
  2080.         return;
  2081.     PR_InitEvent(&event->ce.event, NULL,
  2082.          (PRHandleEventProc)et_HandleEvent_Abort,
  2083.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2084.     event->fn = fn;
  2085.     event->data = data;
  2086.     event->status = status;
  2087.  
  2088.     (void) et_PostEvent(&event->ce, TRUE);
  2089. }
  2090.  
  2091.  
  2092. /****************************************************************************/
  2093.  
  2094. typedef struct {
  2095.     ETEvent         ce;
  2096.     IL_GroupContext    * img_cx;
  2097.     LO_ImageStruct     * img;
  2098.     char               * str;
  2099.     NET_ReloadMethod     how;
  2100. } MozillaEvent_GetImage;
  2101.  
  2102. PR_STATIC_CALLBACK(void)
  2103. et_HandleEvent_GetImage(MozillaEvent_GetImage* e)
  2104. {
  2105.     IL_DisplayData dpy_data;
  2106.     MWContext *pContext = e->ce.context;
  2107.     IL_GroupContext *img_cx = e->img_cx;
  2108.     LO_ImageStruct *lo_image = e->img;
  2109.     const char *url = e->str;
  2110.     
  2111.     if (e->ce.doc_id != XP_DOCID(pContext))
  2112.     return;
  2113.  
  2114.     XP_ASSERT(pContext->color_space);
  2115.     if (!pContext->color_space)
  2116.         return;
  2117.     dpy_data.color_space = pContext->color_space;
  2118.     dpy_data.dither_mode = IL_Auto;
  2119.     IL_SetDisplayMode(img_cx, IL_COLOR_SPACE | IL_DITHER_MODE, &dpy_data);
  2120.     
  2121.     LO_SetImageURL(pContext, img_cx, lo_image, url, e->how);
  2122.     lo_image->pending_mocha_event = PR_FALSE;
  2123. }
  2124.  
  2125. PR_STATIC_CALLBACK(void)
  2126. et_DestroyEvent_GetImage(MozillaEvent_GetImage* e)
  2127. {
  2128.     if (e->str)
  2129.         XP_FREE(e->str);
  2130.     XP_FREE(e);
  2131. }
  2132.  
  2133. void
  2134. ET_il_GetImage(const char * str, MWContext * pContext, IL_GroupContext *img_cx,
  2135.                LO_ImageStruct * image_data, NET_ReloadMethod how)
  2136. {
  2137.  
  2138.     MozillaEvent_GetImage* event = PR_NEW(MozillaEvent_GetImage);
  2139.     if (event == NULL) 
  2140.         return;
  2141.     PR_InitEvent(&event->ce.event, pContext,
  2142.          (PRHandleEventProc)et_HandleEvent_GetImage,
  2143.          (PRDestroyEventProc)et_DestroyEvent_GetImage);
  2144.     event->ce.context = pContext;
  2145.     event->ce.doc_id = XP_DOCID(pContext);
  2146.     event->str = str ? strdup(str) : NULL;
  2147.     event->img_cx = img_cx;
  2148.     event->img = image_data;
  2149.     event->how = how;
  2150.  
  2151.    (void) et_PostEvent(&event->ce, FALSE);
  2152.  
  2153. }
  2154.  
  2155. /****************************************************************************/
  2156.  
  2157. typedef struct {
  2158.     ETEvent        ce;
  2159.     IL_GroupContext    *pImgCX;
  2160.     void        *pDpyCX;
  2161.     JSBool        bAddObserver;
  2162. } MozillaEvent_GroupObserver;
  2163.  
  2164. PR_STATIC_CALLBACK(void)
  2165. et_HandleEvent_SetGroupObserver(MozillaEvent_GroupObserver* e)
  2166. {
  2167.     MWContext *pContext = e->ce.context;
  2168.     IL_DisplayData dpy_data;
  2169.      
  2170.     if (e->bAddObserver)
  2171.     IL_AddGroupObserver(e->pImgCX, FE_MochaImageGroupObserver, pContext);
  2172.     else
  2173.     IL_RemoveGroupObserver(e->pImgCX, FE_MochaImageGroupObserver, pContext);
  2174.  
  2175.     dpy_data.display_context = e->pDpyCX;
  2176.     IL_SetDisplayMode(e->pImgCX, IL_DISPLAY_CONTEXT, &dpy_data);
  2177. }
  2178.  
  2179. void
  2180. ET_il_SetGroupObserver(MWContext * pContext, IL_GroupContext *pImgCX, void *pDpyCX,
  2181.                JSBool bAddObserver)
  2182. {
  2183.  
  2184.     MozillaEvent_GroupObserver* event = PR_NEW(MozillaEvent_GroupObserver);
  2185.     if (event == NULL) 
  2186.         return;
  2187.     PR_InitEvent(&event->ce.event, pContext,
  2188.          (PRHandleEventProc)et_HandleEvent_SetGroupObserver,
  2189.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2190.     event->ce.context = pContext;
  2191.     event->pImgCX = pImgCX;
  2192.     event->pDpyCX = pDpyCX;
  2193.     event->bAddObserver = bAddObserver;
  2194.  
  2195.     (void) et_PostEvent(&event->ce, TRUE);
  2196.  
  2197. }
  2198.  
  2199. /****************************************************************************/
  2200.  
  2201. typedef struct {
  2202.     ETEvent          ce;
  2203.     LO_Element        * ele;
  2204. } MozillaEvent_Form;
  2205.  
  2206. PR_STATIC_CALLBACK(void)
  2207. et_HandleEvent_ResetForm(MozillaEvent_Form* e)
  2208. {
  2209.     LO_ResetForm(e->ce.context, (LO_FormElementStruct *) e->ele);
  2210. }
  2211.  
  2212. void
  2213. ET_lo_ResetForm(MWContext * pContext, LO_Element * ele)
  2214. {
  2215.  
  2216.     MozillaEvent_Form* event = XP_NEW_ZAP(MozillaEvent_Form);
  2217.     if (event == NULL) 
  2218.         return;
  2219.     PR_InitEvent(&event->ce.event, pContext,
  2220.          (PRHandleEventProc)et_HandleEvent_ResetForm,
  2221.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2222.     event->ce.context = pContext;
  2223.     event->ele = ele;
  2224.  
  2225.     (void) et_PostEvent(&event->ce, TRUE);
  2226. }
  2227.  
  2228. /****************************************************************************/
  2229.  
  2230. PR_STATIC_CALLBACK(void)
  2231. et_HandleEvent_SubmitForm(MozillaEvent_Form* e)
  2232. {
  2233. /* XXX - I think this code should be here, but chouck must 
  2234.    have final say - fur
  2235.     if (e->ce.doc_id != XP_DOCID(e->ce.context))
  2236.     return;
  2237. */
  2238.  
  2239.     FE_SubmitInputElement(e->ce.context, e->ele);
  2240. }
  2241.  
  2242. void
  2243. ET_fe_SubmitInputElement(MWContext * pContext, LO_Element * ele)
  2244. {
  2245.  
  2246.     MozillaEvent_Form* event = XP_NEW_ZAP(MozillaEvent_Form);
  2247.     if (event == NULL) 
  2248.         return;
  2249.     PR_InitEvent(&event->ce.event, pContext,
  2250.          (PRHandleEventProc)et_HandleEvent_SubmitForm,
  2251.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2252.     event->ce.context = pContext;
  2253.     event->ce.doc_id = XP_DOCID(pContext);
  2254.     event->ele = ele;
  2255.  
  2256.     (void) et_PostEvent(&event->ce, FALSE);
  2257.  
  2258. }
  2259.  
  2260. /****************************************************************************/
  2261. PR_STATIC_CALLBACK(void*)
  2262. et_HandleEvent_GetSecurityStatus(ETEvent * e)
  2263. {
  2264.     return (void *) XP_GetSecurityStatus(e->context);
  2265. }
  2266.  
  2267. int
  2268. ET_GetSecurityStatus(MWContext * pContext)
  2269. {
  2270.     int ret = 0;
  2271.     ETEvent * event = XP_NEW_ZAP(ETEvent);
  2272.     if (event == NULL) 
  2273.         return -1; /* SSL_SECURITY_STATUS_NOOPT */
  2274.     PR_InitEvent(&event->event, pContext,
  2275.          (PRHandleEventProc)et_HandleEvent_GetSecurityStatus,
  2276.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2277.     event->context = pContext;
  2278.  
  2279.     ret = (int) et_PostEvent(event, TRUE);
  2280.     return ret;
  2281. }
  2282.  
  2283. /****************************************************************************/
  2284.  
  2285. typedef struct {
  2286.     ETEvent          ce;
  2287.     URL_Struct        * pUrl;
  2288.     const char        * wysiwyg_url;
  2289.     const char        * base_href;
  2290.     int32                 layer_id;
  2291. } MozillaEvent_DocCacheConverter;
  2292.  
  2293.  
  2294. PR_STATIC_CALLBACK(void)
  2295. et_HandleEvent_SetWriteStream(MozillaEvent_DocCacheConverter * e)
  2296. {
  2297.     lo_TopState *top_state;
  2298.  
  2299.     top_state = lo_GetMochaTopState(e->ce.context);
  2300.     if (top_state && !top_state->mocha_write_stream) {
  2301.         top_state->mocha_write_stream
  2302.             = NET_CloneWysiwygCacheFile(e->ce.context, 
  2303.                         e->pUrl,
  2304.                         (uint32)top_state->script_bytes,
  2305.                     e->wysiwyg_url,
  2306.                     e->base_href);
  2307.     }
  2308. }
  2309.  
  2310. PR_STATIC_CALLBACK(void)
  2311. et_DestroyEvent_SetWriteStream(MozillaEvent_DocCacheConverter * e)
  2312. {
  2313.     NET_DropURLStruct(e->pUrl);
  2314.     PR_FREEIF((char *) e->wysiwyg_url);
  2315.     PR_FREEIF((char *) e->base_href);
  2316.     XP_FREE(e);
  2317. }
  2318.  
  2319. void
  2320. ET_moz_SetMochaWriteStream(MochaDecoder * decoder)
  2321. {
  2322.     MozillaEvent_DocCacheConverter * event;
  2323.     JSPrincipals *principals;
  2324.  
  2325.     event = XP_NEW_ZAP(MozillaEvent_DocCacheConverter);
  2326.     if (!event) 
  2327.         return;
  2328.  
  2329.     PR_InitEvent(&event->ce.event, decoder->window_context,
  2330.          (PRHandleEventProc)et_HandleEvent_SetWriteStream,
  2331.          (PRDestroyEventProc)et_DestroyEvent_SetWriteStream);
  2332.  
  2333.     event->ce.context = decoder->window_context;
  2334.     event->pUrl = NET_HoldURLStruct(decoder->url_struct);
  2335.     principals = lm_GetPrincipalsFromStackFrame(decoder->js_context);
  2336.     event->wysiwyg_url = lm_MakeWysiwygUrl(decoder->js_context, decoder,
  2337.                                            LO_DOCUMENT_LAYER_ID, principals);
  2338.     event->base_href = LM_GetBaseHrefTag(decoder->js_context, principals);
  2339.  
  2340.     et_PostEvent(&event->ce, TRUE);
  2341. }
  2342.  
  2343.  
  2344. /****************************************************************************/
  2345.  
  2346. PRIVATE NET_StreamClass *
  2347. lm_DocCacheConverterNoHistory(MWContext * context, URL_Struct * url,
  2348.                   const char * wysiwyg_url)
  2349. {
  2350.     lo_TopState *top_state;
  2351.     char *address;
  2352.     NET_StreamClass *cache_stream;
  2353.  
  2354.     top_state = lo_GetMochaTopState(context);
  2355.     if (!top_state)
  2356.     return NULL;
  2357.  
  2358.     /* Save a wysiwyg copy in the URL struct for resize-reloads. */
  2359.     url->wysiwyg_url = XP_STRDUP(wysiwyg_url);
  2360.     if (!url->wysiwyg_url)
  2361.     return NULL;
  2362.     
  2363.     /* Then pass it via url_struct to create a cache converter stream. */
  2364.     address = url->address;
  2365.     url->address = url->wysiwyg_url;
  2366.     cache_stream = NET_CacheConverter(FO_CACHE_ONLY,
  2367.                       (void *)1,    /* XXX don't hold url */
  2368.                       url,
  2369.                       context);
  2370.     url->address = address;
  2371.  
  2372.     top_state->mocha_write_stream = cache_stream;
  2373.     return cache_stream;
  2374. }
  2375.  
  2376. NET_StreamClass *
  2377. lm_DocCacheConverter(MWContext * context, URL_Struct * url,
  2378.              const char * wysiwyg_url)
  2379. {
  2380.     History_entry *he;    
  2381.     NET_StreamClass *cache_stream;
  2382.  
  2383.     cache_stream = lm_DocCacheConverterNoHistory(context, url, wysiwyg_url);
  2384.  
  2385.     /*
  2386.      * Make a copy of wysiwyg_url in our history entry no matter what went
  2387.      * wrong building cache_stream.  This way, NET_GetURL can see the wysiwyg:
  2388.      * prefix, notice when it misses the cache, and clear URL_s->resize_reload
  2389.      * to make the reload from the original/generating URL destructive.
  2390.      */
  2391.     he = SHIST_GetCurrent(&context->hist);
  2392.     if (he) {
  2393.         PR_FREEIF(he->wysiwyg_url);
  2394.         he->wysiwyg_url = XP_STRDUP(wysiwyg_url);
  2395.     }
  2396.  
  2397.     return cache_stream;
  2398. }
  2399.  
  2400. PR_STATIC_CALLBACK(NET_StreamClass *)
  2401. et_HandleEvent_DocCacheConverter(MozillaEvent_DocCacheConverter * e)
  2402. {
  2403.     NET_StreamClass * stream;
  2404.     
  2405.     if (e->layer_id != LO_DOCUMENT_LAYER_ID) {
  2406.         return lm_DocCacheConverterNoHistory(e->ce.context, 
  2407.                                              e->pUrl, 
  2408.                                              e->wysiwyg_url);
  2409.     }
  2410.     
  2411.     stream = lm_DocCacheConverter(e->ce.context, 
  2412.                                   e->pUrl, 
  2413.                                   e->wysiwyg_url);
  2414.     return stream;
  2415. }
  2416.  
  2417. PR_STATIC_CALLBACK(void)
  2418. et_DestroyEvent_DocCacheConverter(MozillaEvent_DocCacheConverter * e)
  2419. {
  2420.     NET_DropURLStruct(e->pUrl);
  2421.     XP_FREE(e);
  2422. }
  2423.  
  2424. NET_StreamClass *
  2425. ET_moz_DocCacheConverter(MWContext * pContext, URL_Struct * pUrl, 
  2426.              char * wysiwyg_url, int32 layer_id)
  2427. {
  2428.     NET_StreamClass * ret = NULL;
  2429.     MozillaEvent_DocCacheConverter * event;
  2430.     
  2431.     event = XP_NEW_ZAP(MozillaEvent_DocCacheConverter);
  2432.     if (!event) 
  2433.         return ret;
  2434.     PR_InitEvent(&event->ce.event, pContext,
  2435.          (PRHandleEventProc)et_HandleEvent_DocCacheConverter,
  2436.          (PRDestroyEventProc)et_DestroyEvent_DocCacheConverter);
  2437.     event->ce.context = pContext;
  2438.     event->pUrl = NET_HoldURLStruct(pUrl);
  2439.     event->wysiwyg_url = wysiwyg_url;
  2440.     event->layer_id = layer_id;
  2441.  
  2442.     ret = et_PostEvent(&event->ce, TRUE);
  2443.     return ret;
  2444. }
  2445.  
  2446. /****************************************************************************/
  2447.  
  2448. PR_STATIC_CALLBACK(void*)
  2449. et_HandleEvent_InitMoja(ETEvent* e)
  2450. {
  2451.     return (void *) LM_InitMoja();
  2452. }
  2453.  
  2454. int
  2455. ET_InitMoja(MWContext* context)
  2456. {
  2457.     int returnCode;
  2458.     ETEvent * event;
  2459.  
  2460.     /* XXX assert that we're on the mocha-thread */
  2461.  
  2462.     /* fast check before sending an event and waiting for it */
  2463.     returnCode = LM_IsMojaInitialized();
  2464.     if (returnCode != LM_MOJA_UNINITIALIZED)
  2465.         return returnCode;
  2466.  
  2467.     event = PR_NEW(ETEvent);
  2468.     if (event == NULL) 
  2469.         return LM_MOJA_OUT_OF_MEMORY;
  2470.     PR_InitEvent(&event->event, context,
  2471.          (PRHandleEventProc)et_HandleEvent_InitMoja,
  2472.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2473.     event->context = context;
  2474.  
  2475.     returnCode = (int) et_PostEvent(event, TRUE);
  2476.     return returnCode;
  2477. }
  2478.  
  2479.  
  2480. /****************************************************************************/
  2481.  
  2482. typedef struct {
  2483.     ETEvent        ce;
  2484.     CL_Layer      * layer;
  2485.     int32        x, y;
  2486.     void          * param_ptr;
  2487.     int32           param_val;
  2488.     ETLayerOp        op;
  2489.     int32        doc_id;
  2490.     char        * referer;
  2491. } MozillaEvent_TweakLayer; 
  2492.  
  2493. PR_STATIC_CALLBACK(int)
  2494. et_HandleEvent_TweakLayer(MozillaEvent_TweakLayer* e)
  2495. {
  2496.     CL_Layer *layer;
  2497.     Bool ret = TRUE;
  2498.  
  2499.     /* check that the doc_id is valid */
  2500.     if(XP_DOCID(e->ce.context) != e->ce.doc_id)
  2501.     return FALSE;
  2502.  
  2503.     switch(e->op) {
  2504.     case CL_SetSrcWidth:
  2505.         ret = LO_SetLayerSrc(e->ce.context, e->param_val, (char*)e->param_ptr,
  2506.                  e->referer, e->x);
  2507.         break;
  2508.     case CL_SetSrc:
  2509.         layer = LO_GetLayerFromId(e->ce.context, e->param_val);
  2510.         ret = LO_SetLayerSrc(e->ce.context, e->param_val, (char*)e->param_ptr, 
  2511.                              e->referer, LO_GetLayerWrapWidth(layer));
  2512.         break;
  2513.     case CL_SetBgColor:
  2514.         LO_SetLayerBgColor(e->layer, (LO_Color*)e->param_ptr);
  2515.         if (e->param_ptr)
  2516.             XP_FREE((void*)e->param_ptr);
  2517.         break;
  2518.     default:
  2519.         XP_ASSERT(0);
  2520.     }
  2521.  
  2522.     return (int)ret;
  2523. }
  2524.  
  2525. PR_STATIC_CALLBACK(void)
  2526. et_DestroyEvent_TweakLayer(MozillaEvent_TweakLayer * event)
  2527. {
  2528.     XP_FREEIF(event->referer);
  2529.     XP_FREE(event);
  2530. }
  2531.  
  2532. /*
  2533.  * These need to be synchronous so that if we set this and then
  2534.  *    immediately look at it we get the correct (new) value
  2535.  */
  2536. int
  2537. ET_TweakLayer(MWContext * context, CL_Layer* layer, int32 x, int32 y,
  2538.               void *param_ptr, int32 param_val, ETLayerOp op,
  2539.           const char *referer, int32 doc_id)
  2540. {
  2541.     MozillaEvent_TweakLayer * event;
  2542.     event = PR_NEW(MozillaEvent_TweakLayer);
  2543.     if (event == NULL) 
  2544.         return NULL;
  2545.  
  2546.     PR_InitEvent(&event->ce.event, context,
  2547.          (PRHandleEventProc)et_HandleEvent_TweakLayer,
  2548.          (PRDestroyEventProc)et_DestroyEvent_TweakLayer);
  2549.     event->ce.context = context;
  2550.     event->ce.doc_id = doc_id;
  2551.     event->layer = layer;
  2552.     event->x = x;
  2553.     event->y = y;
  2554.     event->param_ptr = param_ptr;
  2555.     event->param_val = param_val;
  2556.     event->op = op;
  2557.     event->referer = referer ? XP_STRDUP(referer) : NULL;
  2558.  
  2559.     return (int)et_PostEvent(&event->ce, TRUE);
  2560. }
  2561.  
  2562. /****************************************************************************/
  2563.  
  2564. typedef struct {
  2565.     ETEvent    ce;
  2566.     XP_Bool    refreshInstances;
  2567. } MozillaEvent_RefreshPlugins; 
  2568.  
  2569. PR_STATIC_CALLBACK(void*)
  2570. et_HandleEvent_RefreshPlugins(MozillaEvent_RefreshPlugins* e)
  2571. {
  2572.     return ((void*) NPL_RefreshPluginList(e->refreshInstances));
  2573. }
  2574.  
  2575. int32
  2576. ET_npl_RefreshPluginList(MWContext* context, XP_Bool refreshInstances)
  2577. {
  2578.     int32 ret = -1;
  2579.  
  2580.     MozillaEvent_RefreshPlugins* event = XP_NEW_ZAP(MozillaEvent_RefreshPlugins);
  2581.     if (event == NULL) 
  2582.         return ret;
  2583.  
  2584.     PR_InitEvent(&event->ce.event, context,
  2585.          (PRHandleEventProc)et_HandleEvent_RefreshPlugins,
  2586.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2587.     event->ce.context = context;
  2588.     event->refreshInstances = refreshInstances;
  2589.  
  2590.     ret = (int32) et_PostEvent(&event->ce, TRUE);
  2591.     return ret;
  2592. }
  2593.  
  2594. /****************************************************************************/
  2595.  
  2596. typedef struct {
  2597.     ETEvent          ce;
  2598.     JSContext        * cx;
  2599.     uint          argc;
  2600.     jsval        * argv;
  2601.     jsval        * rval;
  2602.     char            * string;
  2603. } MozillaEvent_HandlePref; 
  2604.  
  2605. PR_STATIC_CALLBACK(JSBool)
  2606. et_HandleEvent_HandlePref(MozillaEvent_HandlePref* e)
  2607. {
  2608.     JSString    * str;
  2609.     char    * cstr;
  2610.     JSContext    * mochaContext=NULL;
  2611.     JSObject    * mochaPrefObject=NULL;
  2612.  
  2613.     str = JS_ValueToString(e->cx, e->argv[0]);
  2614.     if (!str)
  2615.     return JS_TRUE;
  2616.  
  2617.     cstr = JS_GetStringBytes(str);
  2618.  
  2619.     PREF_GetConfigContext(&mochaContext);
  2620.     if (mochaContext == NULL)    {
  2621.         return JS_FALSE;
  2622.     }
  2623.     PREF_GetGlobalConfigObject(&mochaPrefObject);
  2624.     if (mochaPrefObject == NULL)    {
  2625.         return JS_FALSE;
  2626.     }
  2627.  
  2628.     switch(e->argc) {
  2629.  
  2630.     case 1:
  2631.     {
  2632.         int iType = PREF_GetPrefType((const char *)cstr);
  2633.         int32 iRet;
  2634.         XP_Bool bRet;
  2635.         char * pRet;
  2636.  
  2637.         switch (iType) {
  2638.             /* these cases should be defines but...*/
  2639.             case 8:
  2640.                 /* pref is a string*/
  2641.                 PREF_CopyCharPref((const char *)cstr,&pRet);
  2642.                 *e->rval = STRING_TO_JSVAL(pRet);
  2643.                 e->string = pRet;
  2644.                 break;
  2645.             case 16:
  2646.                 /* pref is a int*/                
  2647.                 PREF_GetIntPref((const char *)cstr,&iRet);
  2648.                 *e->rval = INT_TO_JSVAL(iRet);
  2649.                 break;
  2650.             case 32:
  2651.                 /* pref is a bool*/
  2652.                 PREF_GetBoolPref((const char *)cstr,&bRet);
  2653.                 *e->rval = BOOLEAN_TO_JSVAL(bRet);
  2654.                 break;
  2655.         }
  2656.     }
  2657.     break;
  2658.     case 2:
  2659.     {
  2660.         if (JSVAL_IS_STRING(e->argv[1]))    {
  2661.         JSString * valueJSStr = JS_ValueToString(e->cx, e->argv[1]);
  2662.         if (valueJSStr)    {
  2663.             char * valueStr = JS_GetStringBytes(valueJSStr);
  2664.             if (valueStr)
  2665.             PREF_SetCharPref(cstr, valueStr);
  2666.         }
  2667.         }
  2668.         else if (JSVAL_IS_INT(e->argv[1]))    {
  2669.         jsint intVal = JSVAL_TO_INT(e->argv[1]);
  2670.         PREF_SetIntPref(cstr, (int32)intVal);
  2671.         }
  2672.         else if (JSVAL_IS_BOOLEAN(e->argv[1]))    {
  2673.         JSBool boolVal = JSVAL_TO_BOOLEAN(e->argv[1]);
  2674.         PREF_SetBoolPref(cstr, (XP_Bool) boolVal);
  2675.         }
  2676.         else if (JSVAL_IS_NULL(e->argv[1]))    {
  2677.             PREF_DeleteBranch(cstr);
  2678.         }
  2679.         }
  2680.     break;
  2681.     }
  2682.  
  2683.     return JS_TRUE;
  2684.  
  2685. }
  2686.  
  2687. JSBool
  2688. ET_HandlePref(JSContext * cx, uint argc, jsval * argv, jsval * rval)
  2689. {
  2690.  
  2691.     JSBool ret;
  2692.  
  2693.     MozillaEvent_HandlePref* event = XP_NEW_ZAP(MozillaEvent_HandlePref);
  2694.     if (event == NULL) 
  2695.         return JS_TRUE;
  2696.  
  2697.     PR_InitEvent(&event->ce.event, NULL,
  2698.          (PRHandleEventProc)et_HandleEvent_HandlePref,
  2699.          (PRDestroyEventProc)et_DestroyEvent_WaitForIt);
  2700.     event->ce.context = NULL;
  2701.     event->cx = cx;
  2702.     event->argc = argc;
  2703.     event->argv = argv;
  2704.     event->rval = rval;
  2705.  
  2706.     ret = (JSBool) et_PostEvent(&event->ce, TRUE);
  2707.  
  2708.     /* if it was a string we need to convert the string to a JSString */
  2709.     /* do we need to free event->string or does JS own it now ? */
  2710.     if (ret == JS_TRUE && JSVAL_IS_STRING(*event->rval))
  2711.     *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, event->string)); 
  2712.  
  2713.     XP_FREE(event);
  2714.     return ret;
  2715.  
  2716. }
  2717.  
  2718. /****************************************************************************/
  2719.  
  2720. typedef struct {
  2721.     ETEvent            ce;
  2722.     ETVerifyComponentFunc   fn;
  2723.     ETBoolPtrFunc       *pActive_callback;
  2724.     ETVoidPtrFunc       *pStartup_callback;
  2725. } MozillaEvent_VerifyComponentFunc;
  2726.  
  2727. PR_STATIC_CALLBACK(PRBool)
  2728. et_HandleEvent_VerifyComponentFunction(MozillaEvent_VerifyComponentFunc* e)
  2729. {
  2730.    
  2731.     return (PRBool)(e->fn) ((void**)(e->pActive_callback), 
  2732.                 (void**)(e->pStartup_callback));
  2733. }
  2734.  
  2735. PRBool
  2736. ET_moz_VerifyComponentFunction(ETVerifyComponentFunc fn, ETBoolPtrFunc *pActive_callback, 
  2737.                    ETVoidPtrFunc *pStartup_callback)
  2738. {
  2739.     PRBool ret;
  2740.     
  2741.     MozillaEvent_VerifyComponentFunc* event = PR_NEW(MozillaEvent_VerifyComponentFunc);
  2742.     if (event == NULL) 
  2743.     return PR_FALSE;
  2744.  
  2745.     PR_InitEvent(&event->ce.event, NULL,
  2746.          (PRHandleEventProc)et_HandleEvent_VerifyComponentFunction,
  2747.          (PRDestroyEventProc)et_DestroyEvent_GenericEvent);
  2748.     event->fn = fn;
  2749.     /* Pointers must be malloc'd inside libmocha before this call */
  2750.     event->pActive_callback = pActive_callback;
  2751.     event->pStartup_callback = pStartup_callback;
  2752.  
  2753.     ret = (PRBool) et_PostEvent(&event->ce, TRUE);
  2754.     return ret;
  2755. }
  2756.  
  2757. /****************************************************************************/
  2758.  
  2759. typedef struct {
  2760.     ETEvent              ce;
  2761.     ETCompPropGetterFunc fn;
  2762.     char        *name;
  2763. } MozillaEvent_GetterFunc;
  2764.  
  2765. PR_STATIC_CALLBACK(void *)
  2766. et_HandleEvent_CompGetter(MozillaEvent_GetterFunc* e)
  2767. {
  2768.     return (void *)(e->fn)(e->name);
  2769. }
  2770.  
  2771. PR_STATIC_CALLBACK(void)
  2772. et_DestroyEvent_CompGetter(MozillaEvent_GetterFunc * event)
  2773. {
  2774.     if (event->name)
  2775.     XP_FREE(event->name);
  2776.     XP_FREE(event);
  2777. }
  2778.  
  2779. void *
  2780. ET_moz_CompGetterFunction(ETCompPropGetterFunc fn, char *name)
  2781. {
  2782.     MozillaEvent_GetterFunc* event = PR_NEW(MozillaEvent_GetterFunc);
  2783.     if (event == NULL) 
  2784.     return NULL;
  2785.  
  2786.     PR_InitEvent(&event->ce.event, NULL,
  2787.          (PRHandleEventProc)et_HandleEvent_CompGetter,
  2788.          (PRDestroyEventProc)et_DestroyEvent_CompGetter);
  2789.     event->fn = fn;
  2790.     event->name = XP_STRDUP(name);
  2791.  
  2792.     return (void *)et_PostEvent(&event->ce, TRUE);
  2793. }
  2794.  
  2795. /****************************************************************************/
  2796.  
  2797. typedef struct {
  2798.     ETEvent              ce;
  2799.     ETCompPropSetterFunc fn;
  2800.     char        *name;
  2801.     void        *data;
  2802. } MozillaEvent_SetterFunc;
  2803.  
  2804. PR_STATIC_CALLBACK(void)
  2805. et_HandleEvent_CompSetter(MozillaEvent_SetterFunc* e)
  2806. {
  2807.     (e->fn)(e->name, e->data);
  2808. }
  2809.  
  2810. PR_STATIC_CALLBACK(void)
  2811. et_DestroyEvent_CompSetter(MozillaEvent_SetterFunc * event)
  2812. {
  2813.     if (event->name)
  2814.     XP_FREE(event->name);
  2815.     XP_FREE(event);
  2816. }
  2817.  
  2818. void
  2819. ET_moz_CompSetterFunction(ETCompPropSetterFunc fn, char *name, void *data)
  2820. {
  2821.     MozillaEvent_SetterFunc* event = PR_NEW(MozillaEvent_SetterFunc);
  2822.     if (!event || !name) 
  2823.     return;
  2824.  
  2825.     PR_InitEvent(&event->ce.event, NULL,
  2826.          (PRHandleEventProc)et_HandleEvent_CompSetter,
  2827.          (PRDestroyEventProc)et_DestroyEvent_CompSetter);
  2828.     event->fn = fn;
  2829.     event->name = XP_STRDUP(name);
  2830.     event->data = data;
  2831.  
  2832.     (void) et_PostEvent(&event->ce, FALSE);
  2833. }
  2834.  
  2835. /****************************************************************************/
  2836.  
  2837. typedef struct {
  2838.     ETEvent              ce;
  2839.     ETCompMethodFunc     fn;
  2840.     int32         argc;
  2841.     JSCompArg        *argv;
  2842. } MozillaEvent_MethodFunc;
  2843.  
  2844. PR_STATIC_CALLBACK(void *)
  2845. et_HandleEvent_CompMethod(MozillaEvent_MethodFunc* e)
  2846. {
  2847.     return (void *)(e->fn)(e->argc, e->argv);
  2848. }
  2849.  
  2850. PR_STATIC_CALLBACK(void)
  2851. et_DestroyEvent_CompMethod(MozillaEvent_MethodFunc * event)
  2852. {
  2853.     if (event->argv)
  2854.     XP_FREE(event->argv);
  2855.     XP_FREE(event);
  2856. }
  2857.  
  2858. void *
  2859. ET_moz_CompMethodFunction(ETCompMethodFunc fn, int32 argc, JSCompArg *argv)
  2860. {
  2861.     MozillaEvent_MethodFunc* event = PR_NEW(MozillaEvent_MethodFunc);
  2862.     if (!event || !argv) 
  2863.     return NULL;
  2864.  
  2865.     PR_InitEvent(&event->ce.event, NULL,
  2866.          (PRHandleEventProc)et_HandleEvent_CompMethod,
  2867.          (PRDestroyEventProc)et_DestroyEvent_CompMethod);
  2868.     event->fn = fn;
  2869.     event->argc = argc;
  2870.     event->argv = XP_ALLOC(argc * sizeof(JSCompArg));
  2871.     if (event->argv)
  2872.     XP_MEMCPY(event->argv, argv, (argc * sizeof(JSCompArg)));
  2873.  
  2874.     return (void *)et_PostEvent(&event->ce, TRUE);
  2875. }
  2876.