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

  1. /* -*- Mode: C++; tab-width: 8; 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. /*
  20.  * JS reflection of embeds in the current document.  The
  21.  * reflected object is the java object associated with the
  22.  * embed... if there is none then the reflection is JSVAL_NULL.
  23.  */
  24.  
  25. /* Please leave outside of ifdef for windows precompiled headers */
  26. #include "lm.h"
  27.  
  28. #ifdef JAVA
  29.  
  30. #include "xp.h"
  31. #include "layout.h"
  32. #include "np.h"
  33. #include "nppriv.h"
  34. #include "jri.h"
  35. #include "jsjava.h"
  36. #include "jsobj.h"
  37. #include "prlog.h"
  38.  
  39. extern PRLogModuleInfo* Moja;
  40. #define warn    PR_LOG_WARN
  41. #define debug    PR_LOG_DEBUG
  42.  
  43. enum embed_array_slot {
  44.     EMBED_ARRAY_LENGTH = -1
  45. };
  46.  
  47. static JSPropertySpec embed_array_props[] = {
  48.     {lm_length_str, EMBED_ARRAY_LENGTH,
  49.             JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT},
  50.     {0}
  51. };
  52.  
  53. extern JSClass lm_embed_array_class;
  54.  
  55. PR_STATIC_CALLBACK(JSBool)
  56. embed_array_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
  57. {
  58.     JSObjectArray *array;
  59.     MochaDecoder *decoder;
  60.     MWContext *context;
  61.     jsint count, slot;
  62.     LO_EmbedStruct *embed_data;
  63.     int32 active_layer_id;
  64.  
  65.     if (!JSVAL_IS_INT(id))
  66.     return JS_TRUE;
  67.  
  68.     slot = JSVAL_TO_INT(id);
  69.  
  70.     array = JS_GetInstancePrivate(cx, obj, &lm_embed_array_class, NULL);
  71.     if (!array)
  72.     return JS_TRUE;
  73.     decoder = array->decoder;
  74.     context = decoder->window_context;
  75.  
  76.     if (!context) return JS_TRUE;
  77.  
  78.     if (LM_MOJA_OK != ET_InitMoja(context))
  79.         return JS_FALSE;
  80.  
  81.     LO_LockLayout();
  82.     switch (slot) {
  83.       case EMBED_ARRAY_LENGTH:
  84.     active_layer_id = LM_GetActiveLayer(context);
  85.     LM_SetActiveLayer(context, array->layer_id);
  86.     count = LO_EnumerateEmbeds(context, array->layer_id);
  87.     LM_SetActiveLayer(context, active_layer_id);
  88.     if (count > array->length)
  89.         array->length = count;
  90.         *vp = INT_TO_JSVAL(array->length);
  91.     break;
  92.  
  93.       default:
  94.     if (slot < 0) {
  95.         /* Don't mess with user-defined or method properties. */
  96.         LO_UnlockLayout();
  97.         return JS_TRUE;
  98.     }
  99.     embed_data = LO_GetEmbedByIndex(context, array->layer_id, (uint)slot);
  100.     if (embed_data) {
  101.             JSObject *mo = LM_ReflectEmbed(context, embed_data, NULL,
  102.                        array->layer_id, (uint)slot);
  103.             if (!mo) {
  104.                 JS_ReportError(cx,
  105.                  "unable to reflect embed with index %d - not loaded yet?",
  106.                  (uint) slot);
  107.                 goto err;
  108.             }
  109.             *vp = OBJECT_TO_JSVAL(mo);
  110.             XP_ASSERT(slot < array->length);
  111.     } else {
  112.             JS_ReportError(cx, "no embed with index %d\n");
  113.             goto err;
  114.         }
  115.     break;
  116.     }
  117.     LO_UnlockLayout();
  118.     return JS_TRUE;
  119.   err:
  120.     LO_UnlockLayout();
  121.     return JS_FALSE;
  122. }
  123.  
  124. PR_STATIC_CALLBACK(void)
  125. embed_array_finalize(JSContext *cx, JSObject *obj)
  126. {
  127.     JSObjectArray *array;
  128.  
  129.     array = JS_GetPrivate(cx, obj);
  130.     if (!array)
  131.     return;
  132.     DROP_BACK_COUNT(array->decoder);
  133.     JS_free(cx, array);
  134. }
  135.  
  136. JSClass lm_embed_array_class = {
  137.     "EmbedArray", JSCLASS_HAS_PRIVATE,
  138.     JS_PropertyStub, JS_PropertyStub,
  139.     embed_array_getProperty, embed_array_getProperty, JS_EnumerateStub,
  140.     JS_ResolveStub, JS_ConvertStub, embed_array_finalize
  141. };
  142.  
  143. JSObject *
  144. lm_GetEmbedArray(MochaDecoder *decoder, JSObject *document)
  145. {
  146.     JSContext *cx = decoder->js_context;
  147.     JSObject *obj;
  148.     JSObjectArray *array;
  149.     JSDocument *doc;
  150.  
  151.     doc = JS_GetPrivate(cx, document);
  152.     if (!doc)
  153.     return NULL;
  154.  
  155.     obj = doc->embeds;
  156.     if (obj)
  157.     return obj;
  158.  
  159.     array = JS_malloc(cx, sizeof *array);
  160.     if (!array)
  161.         return NULL;
  162.     array->decoder = NULL;  /* in case of error below */
  163.  
  164.     obj = JS_NewObject(cx, &lm_embed_array_class, NULL, document);
  165.     if (!obj || !JS_SetPrivate(cx, obj, array)) {
  166.     JS_free(cx, array);
  167.     return NULL;
  168.     }
  169.  
  170.     if (!JS_DefineProperties(cx, obj, embed_array_props))
  171.     return NULL;
  172.  
  173.     array->decoder = HOLD_BACK_COUNT(decoder);
  174.     array->length = 0;
  175.     array->layer_id = doc->layer_id;
  176.     doc->embeds = obj;
  177.     return obj;
  178. }
  179.  
  180. /* this calls MozillaEmbedContext to reflect the embed by
  181.  * calling into mocha... yow! */
  182. static JSObject *
  183. lm_ReallyReflectEmbed(MWContext *context, LO_EmbedStruct *lo_embed,
  184.                       int32 layer_id, uint32 index)
  185. {
  186.     JSObject *obj;
  187.     MochaDecoder *decoder;
  188.     JSContext *cx;
  189.     jref jembed;
  190.     NPEmbeddedApp* embed;
  191.     lo_TopState *top_state;
  192.     PRHashTable *map;
  193.     PR_LOG(Moja, debug, ("really reflect embed 0x%x\n", lo_embed));
  194.  
  195.     if ((obj = lo_embed->mocha_object) != NULL)
  196.         return obj;
  197.  
  198.     decoder = LM_GetMochaDecoder(context);
  199.     if (!decoder)
  200.     return NULL;
  201.     cx = decoder->js_context;
  202.  
  203.     top_state = lo_GetMochaTopState(context);
  204.     if (top_state->resize_reload) {
  205.         map = lm_GetIdToObjectMap(decoder);
  206.         
  207.         if (map)
  208.             obj = (JSObject *)PR_HashTableLookup(map,
  209.                              LM_GET_MAPPING_KEY(LM_EMBEDS, layer_id, index));
  210.         if (obj) {
  211.             lo_embed->mocha_object = obj;
  212.             return obj;
  213.         }
  214.     }
  215.  
  216.     /* set the element to something bad if we can't get the java obj */
  217.     if (!JSJ_IsEnabled()) {
  218.         PR_LOG(Moja, debug, ("reflected embed 0x%x as null\n",
  219.                              lo_embed));
  220.         return lo_embed->mocha_object = lm_DummyObject;
  221.     }
  222.  
  223.     embed = (NPEmbeddedApp*) lo_embed->FE_Data;
  224.     if (embed) {
  225.         np_data *ndata = (np_data*) embed->np_data;
  226.         np_instance *instance;
  227.  
  228.         /* XXX this comes from npglue.c, it should be put
  229.          * in one of the plugin header files */
  230.         extern jref npn_getJavaPeer(NPP npp);
  231.  
  232.         if (!ndata || ndata->state == NPDataSaved) {
  233.             PR_LOG(Moja, warn, ("embed 0x%x is missing or suspended\n",
  234.                                 lo_embed));
  235.             return NULL;
  236.         }
  237.         instance = ndata->instance;
  238.     if (!instance) return NULL;
  239.         jembed = npn_getJavaPeer(instance->npp);
  240.  
  241.         obj = js_ReflectJObjectToJSObject(decoder->js_context,
  242.                           (HObject *)jembed);
  243.         PR_LOG(Moja, debug, ("reflected embed 0x%x (java 0x%x) to 0x%x ok\n",
  244.                              lo_embed, jembed, obj));
  245.  
  246.         map = lm_GetIdToObjectMap(decoder);
  247.         if (map)
  248.             PR_HashTableAdd(map, 
  249.                             LM_GET_MAPPING_KEY(LM_EMBEDS, layer_id, index),
  250.                             obj);
  251.  
  252.         return lo_embed->mocha_object = obj;
  253.     } else {
  254.         PR_LOG(Moja, warn, ("failed to reflect embed 0x%x\n", lo_embed));
  255.         return NULL;
  256.     }
  257. }
  258.  
  259.  
  260. JSObject *
  261. LM_ReflectEmbed(MWContext *context, LO_EmbedStruct *lo_embed,
  262.                 PA_Tag * tag, int32 layer_id, uint index)
  263. {
  264.     JSObject *obj, *array_obj, *outer_obj, *document;
  265.     MochaDecoder *decoder;
  266.     JSContext *cx;
  267.     char *name;
  268.     int i;
  269.  
  270.     obj = lo_embed->mocha_object;
  271.     if (obj)
  272.         return obj;
  273.  
  274.     decoder = LM_GetMochaDecoder(context);
  275.     if (!decoder)
  276.         return NULL;
  277.  
  278.     cx = decoder->js_context;
  279.  
  280.     /* get the name */
  281.     name = 0;
  282.     for (i = 0; i < lo_embed->attribute_cnt; i++) {
  283.         if (!XP_STRCASECMP(lo_embed->attribute_list[i], "name")) {
  284.             name = strdup(lo_embed->value_list[i]);
  285.             break;
  286.         }
  287.     }
  288.  
  289.     /* Get the document object that will hold this applet */
  290.     document = lm_GetDocumentFromLayerId(decoder, layer_id);
  291.     if (!document) {
  292.         LM_PutMochaDecoder(decoder);
  293.         return NULL;
  294.     }
  295.     
  296.     array_obj = lm_GetEmbedArray(decoder, document);
  297.     if (!array_obj) {
  298.         LM_PutMochaDecoder(decoder);
  299.         return NULL;
  300.     }
  301.  
  302.     /* XXX should pass thru ReallyReflectApplet to whatever calls NewObject */
  303.     outer_obj = lm_GetOuterObject(decoder);
  304.  
  305.     /* this function does the real work */
  306.     obj = lm_ReallyReflectEmbed(context, lo_embed, layer_id, index);
  307.  
  308.     if (!obj)
  309.         goto out;
  310.  
  311.     /* put it in the embed array */
  312.     if (!lm_AddObjectToArray(cx, array_obj, name, index, obj)) {
  313.     obj = NULL;
  314.     goto out;
  315.     }
  316.  
  317.     /* put it in the document scope */
  318.     if (name && !JS_DefineProperty(cx, outer_obj, name, OBJECT_TO_JSVAL(obj),
  319.                    NULL, NULL,
  320.                    JSPROP_ENUMERATE | JSPROP_READONLY)) {
  321.     PR_LOG(Moja, warn, ("failed to define embed 0x%x as %s\n",
  322.                 lo_embed, name));
  323.     /* XXX remove it altogether? */
  324.     }
  325.  
  326.     /* cache it in layout data structure */
  327.     lo_embed->mocha_object = obj;
  328.  
  329. out:
  330.     LM_PutMochaDecoder(decoder);
  331.     return obj;
  332. }
  333.  
  334. PRIVATE JSObject *
  335. LM_ReflectNamedEmbed(MWContext *context, lo_NameList *name_rec, 
  336.                      int32 layer_id, uint index)
  337. {
  338.     return NULL;
  339. }
  340.  
  341. #endif /* JAVA */
  342.