home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / layout / layjava.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  24.9 KB  |  1,004 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. #include "xp.h"
  20. #include "net.h"
  21. #include "pa_parse.h"
  22. #include "layout.h"
  23. #include "laylayer.h"
  24. #include "java.h"
  25. #include "laystyle.h"
  26. #include "layers.h"
  27.  
  28. #define JAVA_DEF_DIM            50
  29. #define JAVA_DEF_BORDER        0
  30. #define JAVA_DEF_VERTICAL_SPACE    0
  31. #define JAVA_DEF_HORIZONTAL_SPACE    0
  32.  
  33. void lo_FinishJavaApp(MWContext *, lo_DocState *, LO_JavaAppStruct *);
  34. static void lo_FormatJavaAppInternal(MWContext *context,
  35.                                      lo_DocState *state,
  36.                                      PA_Tag *tag,
  37.                                      LO_JavaAppStruct *java_app);
  38.  
  39. void
  40. LO_ClearJavaAppBlock(MWContext *context, LO_JavaAppStruct *java_app)
  41. {
  42.     int32 doc_id;
  43.     lo_TopState *top_state;
  44.     lo_DocState *main_doc_state;
  45.     lo_DocState *state;
  46.  
  47.     /*
  48.      * Get the unique document ID, and retreive this
  49.      * documents layout state.
  50.      */
  51.     doc_id = XP_DOCID(context);
  52.     top_state = lo_FetchTopState(doc_id);
  53.     if ((top_state == NULL)||(top_state->doc_state == NULL))
  54.     {
  55.         return;
  56.     }
  57.  
  58.     if (top_state->layout_blocking_element == (LO_Element *)java_app)
  59.     {
  60.         if (java_app->width == 0)
  61.         {
  62.             java_app->width = JAVA_DEF_DIM;
  63.         }
  64.         if (java_app->height == 0)
  65.         {
  66.             java_app->height = JAVA_DEF_DIM;
  67.         }
  68.  
  69.         main_doc_state = top_state->doc_state;
  70.         state = lo_CurrentSubState(main_doc_state);
  71.  
  72.         lo_FinishJavaApp(context, state, java_app);
  73.         lo_FlushBlockage(context, state, main_doc_state);
  74.     }
  75. }
  76.  
  77.  
  78. void
  79. lo_FormatJavaObject(MWContext *context, lo_DocState *state, PA_Tag *tag, LO_JavaAppStruct *java_app)
  80. {
  81.     PA_Block buff;
  82.  
  83.     buff = lo_FetchParamValue(context, tag, PARAM_CLASSID);
  84.     if (buff != NULL)
  85.     {
  86.         char* str;
  87.         PA_LOCK(str, char *, buff);
  88.         if (XP_STRNCASECMP(str, "java:", 5) == 0)
  89.             java_app->selector_type = LO_JAVA_SELECTOR_OBJECT_JAVA;
  90.         else if (XP_STRNCASECMP(str, "javaprogram:", 12) == 0)
  91.             java_app->selector_type = LO_JAVA_SELECTOR_OBJECT_JAVAPROGRAM;
  92.         else if (XP_STRNCASECMP(str, "javabean:", 8) == 0)
  93.             java_app->selector_type = LO_JAVA_SELECTOR_OBJECT_JAVABEAN;
  94.         PA_UNLOCK(buff);
  95.         XP_FREE(buff);
  96.     }
  97.  
  98.     if (java_app->selector_type == LO_JAVA_SELECTOR_OBJECT_JAVAPROGRAM)
  99.     {
  100.         java_app->ele_attrmask |= LO_ELE_HIDDEN;
  101.     }
  102.     else 
  103.     {
  104.         /* Get the HIDDEN parameter */
  105.         java_app->ele_attrmask = 0;
  106.         buff = lo_FetchParamValue(context, tag, PARAM_HIDDEN);
  107.         if (buff != NULL)
  108.         {
  109.             Bool hidden = TRUE;
  110.             char* str;
  111.  
  112.             PA_LOCK(str, char *, buff);
  113.             if (pa_TagEqual("no", str))
  114.             {
  115.                 hidden = FALSE;
  116.             }
  117.             else if (pa_TagEqual("false", str))
  118.             {
  119.                 hidden = FALSE;
  120.             }
  121.             else if (pa_TagEqual("off", str))
  122.             {
  123.                 hidden = FALSE;
  124.             }
  125.             PA_UNLOCK(buff);
  126.             PA_FREE(buff);
  127.  
  128.             if (hidden != FALSE)
  129.             {
  130.                 java_app->ele_attrmask |= LO_ELE_HIDDEN;
  131.             }
  132.         }
  133.     }
  134.  
  135.     /* Finish formatting the object */
  136.     lo_FormatJavaAppInternal(context, state, tag, java_app);
  137. }
  138.  
  139.  
  140. void
  141. lo_FormatJavaApp(MWContext *context, lo_DocState *state, PA_Tag *tag)
  142. {
  143.     LO_JavaAppStruct *java_app;
  144.  
  145.     /*
  146.      * Fill in the java applet structure with default data
  147.      */
  148.     java_app = (LO_JavaAppStruct *)lo_NewElement(context, state, LO_JAVA, NULL, 0);
  149.     if (java_app == NULL)
  150.     {
  151.         return;
  152.     }
  153.  
  154.     java_app->type = LO_JAVA;
  155.     java_app->ele_id = NEXT_ELEMENT;
  156.     java_app->x = state->x;
  157.     java_app->x_offset = 0;
  158.     java_app->y = state->y;
  159.     java_app->y_offset = 0;
  160.     java_app->width = 0;
  161.     java_app->height = 0;
  162.     java_app->next = NULL;
  163.     java_app->prev = NULL;
  164.  
  165.     java_app->ele_attrmask = 0;
  166.     java_app->selector_type = LO_JAVA_SELECTOR_APPLET;
  167.  
  168.     /* Finish formatting the object */
  169.     lo_FormatJavaAppInternal(context, state, tag, java_app);
  170. }
  171.  
  172.  
  173. static void
  174. lo_FormatJavaAppInternal(MWContext *context, lo_DocState *state, PA_Tag *tag, LO_JavaAppStruct *java_app)
  175. {
  176.     PA_Block buff;
  177.     char *str;
  178.     int32 val;
  179.     int32 doc_width;
  180.     Bool widthSpecified = FALSE;
  181.     Bool heightSpecified = FALSE;
  182.     lo_DocLists *doc_lists;
  183.  
  184.     java_app->nextApplet = NULL;
  185. #ifdef MOCHA
  186.     java_app->mocha_object = NULL;
  187. #endif
  188.  
  189.     java_app->FE_Data = NULL;
  190.     java_app->session_data = NULL;
  191.     java_app->line_height = state->line_height;
  192.  
  193.     java_app->base_url = NULL;
  194.     java_app->attr_code = NULL;
  195.     java_app->attr_codebase = NULL;
  196.     java_app->attr_archive = NULL;
  197.     java_app->attr_name = NULL;
  198.  
  199.     java_app->param_cnt = 0;
  200.     java_app->param_names = NULL;
  201.     java_app->param_values = NULL;
  202.  
  203.     java_app->may_script = FALSE;
  204.  
  205.     java_app->alignment = LO_ALIGN_BASELINE;
  206.     java_app->border_width = JAVA_DEF_BORDER;
  207.     java_app->border_vert_space = JAVA_DEF_VERTICAL_SPACE;
  208.     java_app->border_horiz_space = JAVA_DEF_HORIZONTAL_SPACE;
  209.     
  210.     java_app->layer = NULL;
  211.     java_app->tag = tag;
  212.  
  213.     /*
  214.      * Assign a unique index for this object 
  215.      * and increment the master index.
  216.      */
  217.     java_app->embed_index = state->top_state->embed_count++;
  218.  
  219.     /*
  220.      * Save away the base of the document
  221.      */
  222.     buff = PA_ALLOC(XP_STRLEN(state->top_state->base_url) + 1);
  223.     if (buff != NULL)
  224.     {
  225.         char *cp;
  226.         PA_LOCK(cp, char*, buff);
  227.         XP_STRCPY(cp, state->top_state->base_url);
  228.         PA_UNLOCK(buff);
  229.         java_app->base_url = buff;
  230.     }
  231.     else
  232.     {
  233.         state->top_state->out_of_memory = TRUE;
  234.         return;
  235.     }
  236.  
  237.     /*
  238.      * Check for an align parameter
  239.      */
  240.     buff = lo_FetchParamValue(context, tag, PARAM_ALIGN);
  241.     if (buff != NULL)
  242.     {
  243.         Bool floating;
  244.  
  245.         floating = FALSE;
  246.         PA_LOCK(str, char *, buff);
  247.         java_app->alignment = lo_EvalAlignParam(str, &floating);
  248.         if (floating != FALSE)
  249.         {
  250.             java_app->ele_attrmask |= LO_ELE_FLOATING;
  251.         }
  252.         PA_UNLOCK(buff);
  253.         PA_FREE(buff);
  254.     }
  255.  
  256.     /*
  257.      * Get the applet CODE or object CLASSID parameter. In both
  258.      * cases the value is place in java_app->attr_code
  259.      */
  260.     if (java_app->selector_type == LO_JAVA_SELECTOR_APPLET)
  261.     {
  262.         /* APPLET tag CODE attribute */
  263.  
  264.         buff = lo_FetchParamValue(context, tag, PARAM_CODE);
  265.     }
  266.     else
  267.     {
  268.         /* OBJECT tag CLASSID attribute */
  269.  
  270.         char * str1, * str2;
  271.         PA_Block new_buff;
  272.  
  273.         int selectorLength;
  274.  
  275.         selectorLength = 5;
  276.         if (java_app->selector_type == LO_JAVA_SELECTOR_OBJECT_JAVAPROGRAM)
  277.             selectorLength = 12;
  278.         else if (java_app->selector_type == LO_JAVA_SELECTOR_OBJECT_JAVABEAN)
  279.             selectorLength = 9;
  280.  
  281.         buff = lo_FetchParamValue(context, tag, PARAM_CLASSID);
  282.  
  283.         if (buff != NULL)
  284.         {
  285.             /* remove the "java:", "javaprogram:", or "javabean:"
  286.              * protocol selector.
  287.              */
  288.             PA_LOCK(str1, char *, buff);
  289.             new_buff = PA_ALLOC(XP_STRLEN(str1) + 1);
  290.             PA_LOCK(str2, char *, new_buff);
  291.             XP_STRCPY(str2, str1 + selectorLength);
  292.             PA_UNLOCK(new_buff);
  293.             PA_UNLOCK(buff);
  294.             PA_FREE(buff);
  295.             buff = new_buff;
  296.         }
  297.     }
  298.     java_app->attr_code = buff;
  299.  
  300.     /*
  301.      * Check for the loaderbase parameter.
  302.      */
  303.     buff = lo_FetchParamValue(context, tag, PARAM_CODEBASE);
  304.     java_app->attr_codebase = buff;
  305.  
  306.     /*
  307.      * Check for the archive parameter.
  308.      */
  309.     buff = lo_FetchParamValue(context, tag, PARAM_ARCHIVE);
  310.     java_app->attr_archive = buff;
  311.  
  312.     /*
  313.      * Check for a mayscript attribute
  314.      */
  315.     buff = lo_FetchParamValue(context, tag, PARAM_MAYSCRIPT);
  316.     if (buff != NULL)
  317.     {
  318.         java_app->may_script = TRUE;
  319.         PA_FREE(buff);
  320.     }
  321.  
  322.     /*
  323.      * Get the name of this java applet.
  324.      */
  325.     if (java_app->selector_type != LO_JAVA_SELECTOR_APPLET)
  326.         buff = lo_FetchParamValue(context, tag, PARAM_ID);
  327.     else
  328.         buff = lo_FetchParamValue(context, tag, PARAM_NAME);
  329.     if (buff != NULL)
  330.     {
  331.         PA_LOCK(str, char *, buff);
  332.         if (str != NULL)
  333.         {
  334.             int32 len;
  335.  
  336.             len = lo_StripTextWhitespace(str, XP_STRLEN(str));
  337.         }
  338.         PA_UNLOCK(buff);
  339.     }
  340.     java_app->attr_name = buff;
  341.  
  342.     doc_width = state->right_margin - state->left_margin;
  343.  
  344.     /*
  345.      * Get the width parameter, in absolute or percentage.
  346.      * If percentage, make it absolute.
  347.      */
  348.     buff = lo_FetchParamValue(context, tag, PARAM_WIDTH);
  349.     if (buff != NULL)
  350.     {
  351.         Bool is_percent;
  352.  
  353.         PA_LOCK(str, char *, buff);
  354.         val = lo_ValueOrPercent(str, &is_percent);
  355.         if (is_percent != FALSE)
  356.         {
  357.             java_app->percent_width = val;
  358.         }
  359.         else
  360.         {
  361.             java_app->percent_width = 0;
  362.             java_app->width = val;
  363.             val = FEUNITS_X(val, context);
  364.         }
  365.         PA_UNLOCK(buff);
  366.         PA_FREE(buff);
  367.         widthSpecified = TRUE;
  368.     }
  369.     val = LO_GetWidthFromStyleSheet(context, state);
  370.     if(val)
  371.     {
  372.         java_app->width = val;
  373.         widthSpecified = TRUE;
  374.     }
  375.  
  376.     /*
  377.      * Get the height parameter, in absolute or percentage.
  378.      * If percentage, make it absolute.
  379.      */
  380.     buff = lo_FetchParamValue(context, tag, PARAM_HEIGHT);
  381.     if (buff != NULL)
  382.     {
  383.         Bool is_percent;
  384.  
  385.         PA_LOCK(str, char *, buff);
  386.         val = lo_ValueOrPercent(str, &is_percent);
  387.         if (is_percent != FALSE)
  388.         {
  389.             java_app->percent_height = val;
  390.         }
  391.         else
  392.         {
  393.             java_app->percent_height = 0;
  394.             val = FEUNITS_Y(val, context);
  395.         }
  396.         java_app->height = val;
  397.         PA_UNLOCK(buff);
  398.         PA_FREE(buff);
  399.         heightSpecified = TRUE;
  400.     }
  401.  
  402.     val = LO_GetHeightFromStyleSheet(context, state);
  403.     if(val)
  404.     {
  405.         java_app->height = val;
  406.         heightSpecified = TRUE;
  407.     }
  408.  
  409.     /* If they forgot to specify a width, make one up. */
  410.     if (!widthSpecified) {
  411.         val = 0;
  412.         if (heightSpecified) {
  413.             val = java_app->height;
  414.         }
  415.         else if (state->allow_percent_width) {
  416.             val = state->win_width * 90 / 100;
  417.         }
  418.         if (val < 1) {
  419.             val = 600;
  420.         }
  421.         java_app->width = val;
  422.     }
  423.     
  424.     /* If they forgot to specify a height, make one up. */
  425.     if (!heightSpecified) {
  426.         val = 0;
  427.         if (widthSpecified) {
  428.             val = java_app->width;
  429.         }
  430.         else if (state->allow_percent_height) {
  431.             val = state->win_height / 2;
  432.         }
  433.         if (val < 1) {
  434.             val = 400;
  435.         }
  436.         java_app->height = val;
  437.     }
  438.  
  439.     /* After going through all the trouble, just to make sure
  440.      * the object tag HIDDEN case is covered as well.
  441.      */
  442.     if (java_app->ele_attrmask & LO_ELE_HIDDEN)
  443.     {
  444.         java_app->width = 0;
  445.         java_app->height = 0;
  446.     }
  447.  
  448.     /*
  449.      * Get the border parameter.
  450.      */
  451.     buff = lo_FetchParamValue(context, tag, PARAM_BORDER);
  452.     if (buff != NULL)
  453.     {
  454.         PA_LOCK(str, char *, buff);
  455.         val = XP_ATOI(str);
  456.         if (val < 0)
  457.         {
  458.             val = 0;
  459.         }
  460.         java_app->border_width = val;
  461.         PA_UNLOCK(buff);
  462.         PA_FREE(buff);
  463.     }
  464.     java_app->border_width = FEUNITS_X(java_app->border_width, context);
  465.  
  466.     /*
  467.      * Get the extra vertical space parameter.
  468.      */
  469.     buff = lo_FetchParamValue(context, tag, PARAM_VSPACE);
  470.     if (buff != NULL)
  471.     {
  472.         PA_LOCK(str, char *, buff);
  473.         val = XP_ATOI(str);
  474.         if (val < 0)
  475.         {
  476.             val = 0;
  477.         }
  478.         java_app->border_vert_space = val;
  479.         PA_UNLOCK(buff);
  480.         PA_FREE(buff);
  481.     }
  482.     java_app->border_vert_space = FEUNITS_Y(java_app->border_vert_space,
  483.                             context);
  484.  
  485.     /*
  486.      * Get the extra horizontal space parameter.
  487.      */
  488.     buff = lo_FetchParamValue(context, tag, PARAM_HSPACE);
  489.     if (buff != NULL)
  490.     {
  491.         PA_LOCK(str, char *, buff);
  492.         val = XP_ATOI(str);
  493.         if (val < 0)
  494.         {
  495.             val = 0;
  496.         }
  497.         java_app->border_horiz_space = val;
  498.         PA_UNLOCK(buff);
  499.         PA_FREE(buff);
  500.     }
  501.     java_app->border_horiz_space = FEUNITS_X(java_app->border_horiz_space,
  502.                         context);
  503.  
  504.     lo_FillInJavaAppGeometry(state, java_app, FALSE);
  505.  
  506.     /*
  507.      * See if we have some saved embed/java_app session data to restore.
  508.      */
  509.     if (state->top_state->savedData.EmbedList != NULL)
  510.     {
  511.         lo_SavedEmbedListData *embed_list;
  512.         embed_list = state->top_state->savedData.EmbedList;
  513.  
  514.         /*
  515.          * If there is still valid data to restore available.
  516.          */
  517.         if (java_app->embed_index < embed_list->embed_count)
  518.         {
  519.             lo_EmbedDataElement* embed_data_list;
  520.  
  521.             PA_LOCK(embed_data_list, lo_EmbedDataElement*,
  522.                 embed_list->embed_data_list);
  523.             java_app->session_data =
  524.                 embed_data_list[java_app->embed_index].data;
  525.             PA_UNLOCK(embed_list->embed_data_list);
  526.         }
  527.     }
  528.  
  529.     /* put the applet onto the applet list for later
  530.      * possible reflection */
  531.     doc_lists = lo_GetCurrentDocLists(state);
  532.     if (state->in_relayout) {
  533.         int32 i, count;
  534.         LO_JavaAppStruct *prev_applet, *cur_applet;
  535.         
  536.         /*
  537.          * In the interest of changing as little as possible, I'm not
  538.          * going to change the applet_list to be in the order of layout
  539.          * (it is currently in reverse order). Instead, we do what 
  540.          * everybody else does - iterate till the end of the list to get
  541.          * find an element with the correct index.
  542.          * If we're in table relayout, we need to replace the element
  543.          * of the same index in this list with the new layout element
  544.          * to prevent multiple reflection.
  545.          */
  546.         count = 0;
  547.         cur_applet = doc_lists->applet_list;
  548.         while (cur_applet) {
  549.             cur_applet = cur_applet->nextApplet;
  550.             count++;
  551.         }
  552.         
  553.         /* reverse order... */
  554.         prev_applet = NULL;
  555.         cur_applet = doc_lists->applet_list;
  556.         for (i = count-1; i >= 0; i--) {
  557.             if (i == doc_lists->applet_list_count) {
  558.                 /* Copy over the mocha object (it might not exist) */
  559.                 java_app->mocha_object = cur_applet->mocha_object;
  560.  
  561.                 java_app->nextApplet = cur_applet->nextApplet;
  562.  
  563.                 /* Replace the old applet with the new one */
  564.                 if (prev_applet == NULL)
  565.                     doc_lists->applet_list = java_app;
  566.                 else
  567.                     prev_applet->nextApplet = java_app;
  568.                 doc_lists->applet_list_count++;
  569.                 break;
  570.             }
  571.             prev_applet = cur_applet;
  572.             cur_applet = cur_applet->nextApplet;
  573.         }
  574.     }
  575.     else {
  576.         java_app->nextApplet = doc_lists->applet_list;
  577.         doc_lists->applet_list = java_app;
  578.         doc_lists->applet_list_count++;
  579.     }
  580.  
  581.     state->current_java = java_app;
  582.     
  583.     /* don't double-count loading applets due to table relayout */
  584.     if (!state->in_relayout)
  585.     {
  586.         state->top_state->mocha_loading_applets_count++;
  587.     }
  588. }
  589.  
  590.  
  591. void
  592. lo_FinishJavaApp(MWContext *context, lo_DocState *state,
  593.     LO_JavaAppStruct *java_app)
  594. {
  595.     int32 baseline_inc;
  596.     int32 line_inc;
  597.     int32 java_app_height, java_app_width;
  598.  
  599.     if ( java_app->layer == NULL )
  600.         {
  601.         java_app->layer =
  602.           lo_CreateEmbeddedObjectLayer(context, state, (LO_Element*)java_app);
  603.         }
  604.  
  605.     if (java_app->selector_type != LO_JAVA_SELECTOR_OBJECT_JAVAPROGRAM)
  606.     {
  607.         /*
  608.          * Eventually this will never happen since we always
  609.          * have dims here from either the image tag itself or the
  610.          * front end.
  611.          */
  612.         if (java_app->width == 0)
  613.         {
  614.             java_app->width = JAVA_DEF_DIM;
  615.         }
  616.         if (java_app->height == 0)
  617.         {
  618.             java_app->height = JAVA_DEF_DIM;
  619.         }
  620.     }
  621.  
  622.     java_app_width = java_app->width + (2 * java_app->border_width) +
  623.         (2 * java_app->border_horiz_space);
  624.     java_app_height = java_app->height + (2 * java_app->border_width) +
  625.         (2 * java_app->border_vert_space);
  626.  
  627.     /*
  628.      * SEVERE FLOW BREAK!  This may be a floating java_app,
  629.      * which means at this point we go do something completely
  630.      * different.
  631.      */
  632.     if (java_app->ele_attrmask & LO_ELE_FLOATING)
  633.     {
  634.         java_app->x_offset += (int16)java_app->border_horiz_space;
  635.         java_app->y_offset += java_app->border_vert_space;
  636.  
  637.         /*
  638.          * Insert this element into the float list.
  639.          */
  640.         java_app->next = state->float_list;
  641.         state->float_list = (LO_Element *)java_app;
  642.  
  643.         lo_AppendFloatInLineList(state, (LO_Element*)java_app, NULL);
  644.  
  645.         lo_LayoutFloatJavaApp(context, state, java_app, TRUE);
  646.  
  647.         /*
  648.          * Make sure the applet get created on
  649.          * the java side before we ever try to display
  650.          * (which the following if might do).
  651.          */
  652.         if (java_app->session_data == NULL && !EDT_IS_EDITOR( context ))
  653.         {
  654.             /*
  655.              * This creates an applet in the java airspace,
  656.              * sends it the init message and sets up the
  657.              * session_data of the java_app structure.
  658.              */
  659.             LJ_CreateApplet(java_app, context, state->top_state->force_reload);
  660.         }
  661.  
  662.         return;
  663.     }
  664.  
  665.     /*
  666.      * Figure out how to align this java_app.
  667.      * baseline_inc is how much to increase the baseline
  668.      * of previous element of this line.  line_inc is how
  669.      * much to increase the line height below the baseline.
  670.      */
  671.     baseline_inc = 0;
  672.     line_inc = 0;
  673.     /*
  674.      * If we are at the beginning of a line, with no baseline,
  675.      * we first set baseline and line_height based on the current
  676.      * font, then place the image.
  677.      */
  678.     if (state->baseline == 0)
  679.     {
  680.         state->baseline = 0;
  681.     }
  682.  
  683.     java_app->x_offset += (int16)java_app->border_horiz_space;
  684.     java_app->y_offset += java_app->border_vert_space;
  685.  
  686.     lo_LayoutInflowJavaApp(context, state, java_app, FALSE, &line_inc, &baseline_inc);
  687.  
  688.     lo_AppendToLineList(context, state,
  689.         (LO_Element *)java_app, baseline_inc);
  690.  
  691.     lo_UpdateStateAfterJavaAppLayout(state, java_app, line_inc, baseline_inc);
  692.  
  693.     if (java_app->session_data == NULL && !EDT_IS_EDITOR( context )) {
  694.         /*
  695.         ** This creates an applet in the java airspace, sends it the init
  696.         ** message and sets up the session_data of the java_app structure:
  697.         */
  698.         LJ_CreateApplet(java_app, context, state->top_state->force_reload);
  699.     }
  700. }
  701.  
  702.  
  703. void
  704. lo_CloseJavaApp(MWContext *context, lo_DocState *state,
  705.     LO_JavaAppStruct *java_app)
  706. {
  707.     /*
  708.     ** Create the applet first (if there wasn't a saved one in the
  709.     ** history).  That way we'll be able to remember reload method.
  710.     */
  711.     if (java_app->session_data == NULL && !EDT_IS_EDITOR( context )) {
  712.         /*
  713.         ** This creates an applet in the java airspace, sends it the init
  714.         ** message and sets up the session_data of the java_app structure:
  715.         */
  716.         LJ_CreateApplet(java_app, context, state->top_state->force_reload);
  717.  
  718.                 lo_AddEmbedData(context, java_app->session_data, 
  719.                                 LJ_DeleteSessionData, 
  720.                                 java_app->embed_index); 
  721.     }
  722.  
  723.     /*
  724.      * Have the front end fetch this java applet, and tells us
  725.      * its dimentions if it knows them.
  726.      */
  727.     FE_GetJavaAppSize(context, java_app, state->top_state->force_reload);
  728.  
  729.     /*
  730.      * We may have to block on this java applet until later
  731.      * when the front end can give us the width and height.
  732.      *
  733.      * Actaully this never can be the case in the current code
  734.      * for applet tag, and since the object tag *can* be 0,0 this
  735.      * is being commented out.
  736.      */
  737.     /*
  738.     if ((java_app->width == 0)||(java_app->height == 0))
  739.     {
  740.         state->top_state->layout_blocking_element =
  741.             (LO_Element *)java_app;
  742.     }
  743.     else
  744.     {
  745.         lo_FinishJavaApp(context, state, java_app);
  746.     }
  747.     */
  748.     lo_FinishJavaApp(context, state, java_app);
  749.  
  750.     state->current_java = NULL;
  751. }
  752.  
  753.  
  754. void
  755. lo_RelayoutJavaApp(MWContext *context, lo_DocState *state, PA_Tag *tag,
  756.     LO_JavaAppStruct *java_app )
  757. {
  758.     lo_DocLists *doc_lists;
  759.  
  760.     lo_PreLayoutTag ( context, state, tag );
  761.     if (state->top_state->out_of_memory)
  762.     {
  763.         return;
  764.     }
  765.  
  766.     java_app->x = state->x;
  767.     java_app->x_offset = 0;
  768.     java_app->y = state->y;
  769.     java_app->y_offset = 0;
  770.  
  771.     /*
  772.      * Assign a unique index for this object 
  773.      * and increment the master index.
  774.      */
  775.     java_app->embed_index = state->top_state->embed_count++;
  776.  
  777.     /*
  778.      * Since we saved the applet_list_count during table relayout,
  779.      * we increment it as if we were reprocessing the APPLET tag.
  780.      */
  781.     doc_lists = lo_GetCurrentDocLists(state);
  782.     doc_lists->applet_list_count++;
  783.     
  784.     state->current_java = java_app;
  785.  
  786.     lo_PostLayoutTag ( context, state, tag, FALSE );
  787. }
  788.  
  789. void
  790. lo_FillInJavaAppGeometry(lo_DocState *state,
  791.                          LO_JavaAppStruct *java_app,
  792.                          Bool relayout)
  793. {
  794.     int32 doc_width;
  795.  
  796.     if (relayout == TRUE)
  797.     {
  798.         java_app->ele_id = NEXT_ELEMENT;
  799.     }
  800.     java_app->x = state->x;
  801.     java_app->y = state->y;
  802.  
  803.     doc_width = state->right_margin - state->left_margin;
  804.  
  805.     /*
  806.      * Get the width parameter, in absolute or percentage.
  807.      * If percentage, make it absolute.
  808.      */
  809.  
  810.     if (java_app->percent_width > 0) {
  811.         int32 val = java_app->percent_width;
  812.         if (state->allow_percent_width == FALSE) {
  813.             val = 0;
  814.         }
  815.         else {
  816.             val = doc_width * val / 100;
  817.         }
  818.         java_app->width = val;
  819.     }
  820.  
  821.     /* Set java_app->height if java_app has a % height specified */
  822.     if (java_app->percent_height > 0) {
  823.         int32 val = java_app->percent_height;
  824.         if (state->allow_percent_height == FALSE) {
  825.             val = 0;
  826.         }
  827.         else {
  828.             val = state->win_height * val / 100;
  829.         }
  830.         java_app->height = val;
  831.     }
  832. }
  833.  
  834. void
  835. lo_LayoutInflowJavaApp(MWContext *context,
  836.                        lo_DocState *state,
  837.                        LO_JavaAppStruct *java_app,
  838.                        Bool inRelayout,
  839.                        int32 *line_inc,
  840.                        int32 *baseline_inc)
  841. {
  842.   int32 java_app_width, java_app_height;
  843.   Bool line_break;
  844.   PA_Block buff;
  845.   char *str;
  846.   LO_TextStruct tmp_text;
  847.   LO_TextInfo text_info;
  848.  
  849.     /*
  850.      * All this work is to get the text_info filled in for the current
  851.      * font in the font stack. Yuck, there must be a better way.
  852.      */
  853.     memset (&tmp_text, 0, sizeof (tmp_text));
  854.     buff = PA_ALLOC(1);
  855.     if (buff == NULL)
  856.     {
  857.         state->top_state->out_of_memory = TRUE;
  858.         return;
  859.     }
  860.     PA_LOCK(str, char *, buff);
  861.     str[0] = ' ';
  862.     PA_UNLOCK(buff);
  863.     tmp_text.text = buff;
  864.     tmp_text.text_len = 1;
  865.     tmp_text.text_attr =
  866.         state->font_stack->text_attr;
  867.     FE_GetTextInfo(context, &tmp_text, &text_info);
  868.     PA_FREE(buff);
  869.  
  870.     java_app_width = java_app->width + (2 * java_app->border_width) +
  871.         (2 * java_app->border_horiz_space);
  872.     java_app_height = java_app->height + (2 * java_app->border_width) +
  873.         (2 * java_app->border_vert_space);
  874.  
  875.     /*
  876.      * Will this java_app make the line too wide.
  877.      */
  878.     if ((state->x + java_app_width) > state->right_margin)
  879.     {
  880.         line_break = TRUE;
  881.     }
  882.     else
  883.     {
  884.         line_break = FALSE;
  885.     }
  886.  
  887.     /*
  888.      * if we are at the beginning of the line.  There is
  889.      * no point in breaking, we are just too wide.
  890.      * Also don't break in unwrapped preformatted text.
  891.      * Also can't break inside a NOBR section.
  892.      */
  893.     if ((state->at_begin_line != FALSE)||
  894.         (state->preformatted == PRE_TEXT_YES)||
  895.         (state->breakable == FALSE))
  896.     {
  897.         line_break = FALSE;
  898.     }
  899.  
  900.     /*
  901.      * break on the java_app if we have
  902.      * a break.
  903.      */
  904.     if (line_break != FALSE)
  905.     {
  906.         /*
  907.          * We need to make the elements sequential, linefeed
  908.          * before java app.
  909.          */
  910.         state->top_state->element_id = java_app->ele_id;        
  911.  
  912.         if (!inRelayout)
  913.         {
  914.             lo_SoftLineBreak(context, state, TRUE);
  915.         }
  916.         else 
  917.         {
  918.             lo_rl_AddSoftBreakAndFlushLine(context, state);
  919.         }
  920.         
  921.         java_app->x = state->x;
  922.         java_app->y = state->y;
  923.         java_app->ele_id = NEXT_ELEMENT;
  924.     }
  925.  
  926.  
  927.     lo_CalcAlignOffsets(state, &text_info, java_app->alignment,
  928.                         java_app_width, java_app_height,
  929.                         &java_app->x_offset, &java_app->y_offset,
  930.                         line_inc, baseline_inc);
  931. }
  932.  
  933. void
  934. lo_LayoutFloatJavaApp(MWContext *context,
  935.                       lo_DocState *state,
  936.                       LO_JavaAppStruct *java_app,
  937.                       Bool updateFE)
  938. {
  939.   int32 java_app_width;
  940.  
  941.   java_app_width = (2 * java_app->border_width) +
  942.     (2 * java_app->border_horiz_space);
  943.  
  944.   if (java_app->alignment == LO_ALIGN_RIGHT)
  945.     {
  946.       java_app->x = state->right_margin - java_app_width;
  947.       if (java_app->x < 0)
  948.         {
  949.           java_app->x = 0;
  950.         }
  951.     }
  952.   else
  953.     {
  954.       java_app->x = state->left_margin;
  955.     }
  956.   
  957.   java_app->y = -1;
  958.   lo_AddMarginStack(state, java_app->x, java_app->y,
  959.                     java_app->width, java_app->height,
  960.                     java_app->border_width,
  961.                     java_app->border_vert_space,
  962.                     java_app->border_horiz_space,
  963.                     java_app->alignment);
  964.  
  965.   if (state->at_begin_line != FALSE)
  966.     {
  967.       lo_FindLineMargins(context, state, updateFE);
  968.       state->x = state->left_margin;
  969.     }
  970. }
  971.  
  972. void
  973. lo_UpdateStateAfterJavaAppLayout(lo_DocState *state,
  974.                                  LO_JavaAppStruct *java_app,
  975.                                  int32 line_inc,
  976.                                  int32 baseline_inc)
  977. {
  978.   int32 java_app_width;
  979.   int32 x, y;
  980.  
  981.   java_app_width = java_app->width + (2 * java_app->border_width) +
  982.     (2 * java_app->border_horiz_space);
  983.  
  984.   state->baseline += (intn) baseline_inc;
  985.   state->line_height += (intn) (baseline_inc + line_inc);
  986.   
  987.   /*
  988.    * Clean up state
  989.    */
  990.   state->x = state->x + java_app->x_offset +
  991.     java_app_width - java_app->border_horiz_space;
  992.   state->linefeed_state = 0;
  993.   state->at_begin_line = FALSE;
  994.   state->trailing_space = FALSE;
  995.   state->cur_ele_type = LO_JAVA;
  996.  
  997.   /* Determine the new position of the layer. */
  998.   x = java_app->x + java_app->x_offset + java_app->border_width;
  999.   y = java_app->y + java_app->y_offset + java_app->border_width;
  1000.   
  1001.   /* Move layer to new position */
  1002.   CL_MoveLayer(java_app->layer, x, y);
  1003. }
  1004.