зеркало из https://github.com/mozilla/pluotsorbet.git
Merge branch 'master' of https://github.com/andreasgal/j2me.js into pimproxy_natives
This commit is contained in:
Коммит
0c0c4136e8
|
@ -6,6 +6,7 @@ certs/j2se_main.ks
|
|||
certs/j2se_test.ks
|
||||
tests/Testlets.java
|
||||
test.log
|
||||
output/
|
||||
|
||||
# These are generated by the Java pre-processor. They're generated from
|
||||
# their *.jpp equivalents. Keep them up-to-date when you add *.jpp files!
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.nokia.mid.ui;
|
||||
|
||||
import javax.microedition.lcdui.Canvas;
|
||||
import javax.microedition.lcdui.Display;
|
||||
|
||||
public abstract class CanvasItem {
|
||||
public static final int SCALE_NOT_ALLOWED = 0;
|
||||
public static final int SCALE_NEAREST = 1;
|
||||
|
@ -46,7 +49,24 @@ public abstract class CanvasItem {
|
|||
native public int getHeight();
|
||||
|
||||
// Sets the rendering position of this CanvasItem.
|
||||
native public void setPosition(int x, int y);
|
||||
native public void setPosition0(int x, int y);
|
||||
|
||||
public void setPosition(int x, int y) {
|
||||
// The passed coordinate is relative to the parent canvas, we need to add up
|
||||
// the anchor value of the parent to get the right coordinate in HTML.
|
||||
if (!(parent instanceof Canvas)) {
|
||||
setPosition0(x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
Display display = ((Canvas)parent).getCurrentDisplay();
|
||||
if (display == null) {
|
||||
setPosition0(x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
setPosition0(display.getDisplayableAnchorX() + x, display.getDisplayableAnchorY() + y);
|
||||
}
|
||||
|
||||
// Sets the Z-position, or the elevation, of the item.
|
||||
public void setZPosition(int z) throws IllegalArgumentException {
|
||||
|
|
|
@ -0,0 +1,908 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
* 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License version 2 for more details (a copy is
|
||||
* included at /legal/license.txt).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* version 2 along with this work; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA
|
||||
*
|
||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
||||
* Clara, CA 95054 or visit www.sun.com if you need additional
|
||||
* information or have any questions.
|
||||
*/
|
||||
|
||||
package com.sun.midp.chameleon;
|
||||
|
||||
import com.sun.midp.chameleon.layers.*;
|
||||
import com.sun.midp.chameleon.skins.*;
|
||||
import com.sun.midp.log.Logging;
|
||||
import com.sun.midp.log.LogChannels;
|
||||
|
||||
import javax.microedition.lcdui.*;
|
||||
|
||||
/**
|
||||
* The MIDPWindow class is a concrete instance of a CWindow which
|
||||
* implements the MIDP specification and its graphical elements,
|
||||
* such as a title bar, soft buttons, ticker, etc.
|
||||
*/
|
||||
public class MIDPWindow extends CWindow {
|
||||
|
||||
// The order of layers id is impotant during creation and updating
|
||||
|
||||
/** Id of layer containing the alert wash */
|
||||
public static final int ALERT_WASH_LAYER = 0;
|
||||
|
||||
/** Id of layer containing the alert displayable */
|
||||
public static final int ALERT_LAYER = 1;
|
||||
|
||||
/** Id of layer containing the mail */
|
||||
public static final int WASH_LAYER = 2;
|
||||
|
||||
/** Id of layer rendering the soft button controls */
|
||||
public static final int BTN_LAYER = 3;
|
||||
|
||||
/** Id of layer containing the ticker of the current displayable */
|
||||
public static final int TICKER_LAYER = 4;
|
||||
|
||||
/** Id of layer containing the title of the current displayable */
|
||||
public static final int TITLE_LAYER = 5;
|
||||
|
||||
/** Id of layer containing the pti contents */
|
||||
public static final int PTI_LAYER = 6;
|
||||
|
||||
/** Id of layer containing the virtual keyboard contents */
|
||||
public static final int KEYBOARD_LAYER = 7;
|
||||
|
||||
/** Id of layer containing the current displayable's contents */
|
||||
public static final int BODY_LAYER = 8;
|
||||
|
||||
/** Number of main layers*/
|
||||
public static final int LAST_LAYER = 9;
|
||||
|
||||
/** Used to call back into the Display class from this package */
|
||||
ChamDisplayTunnel tunnel;
|
||||
|
||||
/** Cached typed references to the namded layers */
|
||||
private WashLayer washLayer;
|
||||
private WashLayer alertWashLayer;
|
||||
private AlertLayer alertLayer;
|
||||
private TitleLayer titleLayer;
|
||||
private TickerLayer tickerLayer;
|
||||
private SoftButtonLayer buttonLayer;
|
||||
private PTILayer ptiLayer;
|
||||
private VirtualKeyboardLayer keyboardLayer;
|
||||
private BodyLayer bodyLayer;
|
||||
|
||||
// layout modes
|
||||
/**
|
||||
* Normal screen mode
|
||||
*/
|
||||
private static final int NORMAL_MODE = 0;
|
||||
|
||||
/**
|
||||
* Full screen mode when the current displayable
|
||||
* is occupying as much screen as possible
|
||||
*/
|
||||
private static final int FULL_SCR_MODE = 1;
|
||||
|
||||
/**
|
||||
* Current screen mode
|
||||
*/
|
||||
int screenMode;
|
||||
|
||||
/** Cache of screen commands */
|
||||
Command[] scrCmdCache;
|
||||
|
||||
/** Number of screen commands in the cache */
|
||||
int scrCmdCount;
|
||||
|
||||
/** Listener to notify when a screen command is selected */
|
||||
CommandListener scrCmdListener;
|
||||
|
||||
/** Cache of selected item commands */
|
||||
Command[] itemCmdCache;
|
||||
|
||||
/** Number of item commands in the cache */
|
||||
int itemCmdCount;
|
||||
|
||||
/** Listener to notify when an item command is selected */
|
||||
ItemCommandListener itemCmdListener;
|
||||
|
||||
CLayer[] mainLayers = new CLayer[LAST_LAYER];
|
||||
|
||||
/** Determines whether area of the window has been changed */
|
||||
boolean sizeChangedOccured = false;
|
||||
|
||||
/** Indicates if body layer was checked for optimized Canvas painting */
|
||||
boolean bodyChecked = false;
|
||||
|
||||
/** Indicates wheher body layer is overlapped with a visible layer */
|
||||
boolean bodyOverlapped = false;
|
||||
|
||||
/**
|
||||
* Construct a new MIDPWindow given the tunnel to the desired
|
||||
* MIDP Display instance
|
||||
*
|
||||
* @param tunnel the "tunnel" to make calls from this java package
|
||||
* back into the Display object in another package
|
||||
*/
|
||||
public MIDPWindow(ChamDisplayTunnel tunnel) {
|
||||
super(ScreenSkin.IMAGE_BG, ScreenSkin.COLOR_BG,
|
||||
tunnel.getDisplayWidth(), tunnel.getDisplayHeight());
|
||||
|
||||
this.tunnel = tunnel;
|
||||
|
||||
for (int i = LAST_LAYER - 1; i >= 0; i-- ) {
|
||||
createLayer(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a repaint. This method does not require any bounds
|
||||
* information as it is contained in each of the Chameleon layers.
|
||||
* This method simply results in a repaint event being placed in
|
||||
* the event queue for a future callback.
|
||||
*/
|
||||
public void requestRepaint() {
|
||||
if (tunnel != null) {
|
||||
tunnel.scheduleRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title of this MIDPWindow. This would typically
|
||||
* correspond to the title of the current displayable, and
|
||||
* may result in the title layer appearing or disappearing.
|
||||
*
|
||||
* @param title the value of the title. null indicates there
|
||||
* is no title.
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
if (titleLayer.setTitle(title)) {
|
||||
resize();
|
||||
}
|
||||
requestRepaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ticker of this MIDPWindow. This would typically
|
||||
* correspond to the ticker of the current displayable, and
|
||||
* may result in the ticker layer appearing or disappearing.
|
||||
*
|
||||
* @param ticker the current Ticker object. null indicates there
|
||||
* is no ticker.
|
||||
*/
|
||||
public void setTicker(Ticker ticker) {
|
||||
if (tickerLayer.setText((ticker != null) ? ticker.getString() : null)) {
|
||||
resize();
|
||||
}
|
||||
requestRepaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert this MIDPWindow that the given displayable is now current
|
||||
* and should be shown on the screen.
|
||||
*
|
||||
* This will establish the given displayable on the screen,
|
||||
* as well as reflect the displayable's title and ticker (if any).
|
||||
* Special circumstances may occur if the displayable is an Alert,
|
||||
* such as maintaining the current screen contents and showing the
|
||||
* Alert in a popup.
|
||||
*
|
||||
* @param displayable the newly current displayable to show
|
||||
* @param height the preferred height of the new displayable
|
||||
*/
|
||||
public void showDisplayable(Displayable displayable, int height) {
|
||||
bodyLayer.opaque = (displayable instanceof Canvas);
|
||||
|
||||
Ticker t = displayable.getTicker();
|
||||
tickerLayer.setText((t != null) ? t.getString() : null);
|
||||
|
||||
if (displayable instanceof Alert) {
|
||||
tickerLayer.toggleAlert(true);
|
||||
buttonLayer.toggleAlert(true);
|
||||
|
||||
// alert does not use title layer. The title is a part of content
|
||||
titleLayer.setTitle(null);
|
||||
|
||||
alertLayer.setAlert(true, (Alert)displayable, height);
|
||||
|
||||
paintWash(false);
|
||||
addLayer(alertLayer);
|
||||
} else {
|
||||
titleLayer.setTitle(displayable.getTitle());
|
||||
bodyLayer.setVisible(true);
|
||||
}
|
||||
addLayer(tickerLayer);
|
||||
|
||||
resize();
|
||||
requestRepaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert this MIDPWindow that the given displayable is no longer
|
||||
* current and should be removed from the screen.
|
||||
*
|
||||
* Special circumstances may occur if the displayable is an Alert,
|
||||
* such as removing the popup and re-instating the previous
|
||||
* displayable which was visible before the Alert popped up.
|
||||
*
|
||||
* @param displayable the newly current displayable to show
|
||||
*/
|
||||
public void hideDisplayable(Displayable displayable) {
|
||||
if (displayable instanceof Alert) {
|
||||
buttonLayer.toggleAlert(false);
|
||||
tickerLayer.toggleAlert(false);
|
||||
|
||||
paintWash(false);
|
||||
alertLayer.setAlert(false, null, 0);
|
||||
removeLayer(alertLayer);
|
||||
} else {
|
||||
bodyLayer.setVisible(false);
|
||||
}
|
||||
|
||||
removeLayer(tickerLayer);
|
||||
|
||||
buttonLayer.dismissMenu();
|
||||
|
||||
// Make sure that not of the popups are shown
|
||||
clearPopups();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the system menu is currently visible. This can be useful
|
||||
* in determining the current isShown() status of the displayable.
|
||||
*
|
||||
* @return true if the system menu is up
|
||||
*/
|
||||
public boolean systemMenuUp() {
|
||||
return buttonLayer.systemMenuUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a repaint of a region of the current displayable.
|
||||
* This method specifically marks a region of the body layer
|
||||
* (which renders the displayable's contents) as dirty and
|
||||
* results in a repaint request being scheduled. The coordinates
|
||||
* are in the space of the displayable itself - that is, 0,0
|
||||
* represents the top left corner of the body layer.
|
||||
*
|
||||
* @param x the x coordinate of the dirty region
|
||||
* @param y the y coordinate of the dirty region
|
||||
* @param w the width of the dirty region
|
||||
* @param h the height of the dirty region
|
||||
*/
|
||||
public void repaintDisplayable(int x, int y, int w, int h) {
|
||||
// We mark the body layer as dirty
|
||||
if (alertLayer.visible) {
|
||||
alertLayer.addDirtyRegion(x, y, w, h);
|
||||
} else {
|
||||
bodyLayer.addDirtyRegion(x, y, w, h);
|
||||
}
|
||||
requestRepaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given layer to this window. This method is
|
||||
* overridden from CWindow in order to special case
|
||||
* popup layers. Popup layers can have their own commands
|
||||
* which supercede those of the current displayable.
|
||||
*
|
||||
* @param layer the CLayer to add to this window
|
||||
* @return true if new layer was added, false otherwise
|
||||
*/
|
||||
public boolean addLayer(CLayer layer) {
|
||||
boolean added = super.addLayer(layer);
|
||||
if (added) {
|
||||
if (layer instanceof PopupLayer) {
|
||||
PopupLayer popup = (PopupLayer)layer;
|
||||
popup.setDirty();
|
||||
popup.visible = true;
|
||||
|
||||
Command[] cmds = popup.getCommands();
|
||||
if (cmds != null) {
|
||||
buttonLayer.updateCommandSet(
|
||||
null, 0, null, cmds, cmds.length,
|
||||
popup.getCommandListener());
|
||||
}
|
||||
}
|
||||
|
||||
if (layer instanceof PTILayer) {
|
||||
ptiLayer = (PTILayer)layer;
|
||||
mainLayers[PTI_LAYER] = layer;
|
||||
resize();
|
||||
} else if (layer instanceof VirtualKeyboardLayer) {
|
||||
keyboardLayer = (VirtualKeyboardLayer)layer;
|
||||
mainLayers[KEYBOARD_LAYER] = layer;
|
||||
resize();
|
||||
} else {
|
||||
layer.update(mainLayers);
|
||||
}
|
||||
}
|
||||
if (added && layer instanceof VirtualKeyboardLayer) {
|
||||
keyboardLayer = (VirtualKeyboardLayer)layer;
|
||||
mainLayers[KEYBOARD_LAYER] = layer;
|
||||
resize();
|
||||
}
|
||||
|
||||
return added;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given layer from this window. This method is
|
||||
* overridden from CWindow in order to special case popup
|
||||
* layers. Popup layers can have their own commands which
|
||||
* supercede those of the current displayable. In this case,
|
||||
* the popup is removed and the commands in the soft button
|
||||
* bar are restored to either the next top-most popup layer
|
||||
* or the current displayable itself.
|
||||
*
|
||||
* @param layer the CLayer to remove from this window
|
||||
* @return true if the layer was able to be removed
|
||||
*/
|
||||
public boolean removeLayer(CLayer layer) {
|
||||
if (super.removeLayer(layer)) {
|
||||
if (layer instanceof PopupLayer) {
|
||||
if (layer == mainLayers[PTI_LAYER]) {
|
||||
ptiLayer = null;
|
||||
mainLayers[PTI_LAYER] = null;
|
||||
resize();
|
||||
}
|
||||
if (layer == mainLayers[KEYBOARD_LAYER]) {
|
||||
keyboardLayer = null;
|
||||
mainLayers[KEYBOARD_LAYER] = null;
|
||||
resize();
|
||||
}
|
||||
|
||||
// Now we update the command set with either the
|
||||
// next top most popup or the original cached commands
|
||||
PopupLayer p = getTopMostPopup();
|
||||
if (p != null && p.getCommands() != null) {
|
||||
Command[] cmds = p.getCommands();
|
||||
buttonLayer.updateCommandSet(
|
||||
null, 0, null, cmds, cmds.length, p.getCommandListener());
|
||||
} else {
|
||||
buttonLayer.updateCommandSet(
|
||||
itemCmdCache, itemCmdCount, itemCmdListener,
|
||||
scrCmdCache, scrCmdCount, scrCmdListener);
|
||||
}
|
||||
} // instanceof
|
||||
return true;
|
||||
} // removeLayer
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return bounds of BodyLayer currently
|
||||
* @return array of bounds
|
||||
*/
|
||||
public int[] getBodyLayerBounds() {
|
||||
int[] innerBounds = new int[4];
|
||||
System.arraycopy(bodyLayer.bounds,0,innerBounds,0,4);
|
||||
return innerBounds;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this MIDPWindow's current command set to match the
|
||||
* current displayable and possibly item selection.
|
||||
*
|
||||
* @param itemCommands the set of item specific commands
|
||||
* @param itemCmdCount the number of item commands
|
||||
* @param itemCmdListener the notification listener for item commands
|
||||
* @param scrCommands the set of screen specific commands
|
||||
* @param scrCmdCount the number of screen commands
|
||||
* @param scrCmdListener the notification listener for screen commands
|
||||
*/
|
||||
public void updateCommandSet(Command[] itemCommands,
|
||||
int itemCmdCount,
|
||||
ItemCommandListener itemCmdListener,
|
||||
Command[] scrCommands,
|
||||
int scrCmdCount,
|
||||
CommandListener scrCmdListener)
|
||||
{
|
||||
// We cache commands to easily reset them when a
|
||||
// popup takes precedence and then is dismissed
|
||||
this.itemCmdCache = itemCommands;
|
||||
this.itemCmdCount = itemCmdCount;
|
||||
this.itemCmdListener = itemCmdListener;
|
||||
this.scrCmdCache = scrCommands;
|
||||
this.scrCmdCount = scrCmdCount;
|
||||
this.scrCmdListener = scrCmdListener;
|
||||
|
||||
buttonLayer.updateCommandSet(itemCommands, itemCmdCount,
|
||||
itemCmdListener,
|
||||
scrCommands, scrCmdCount,
|
||||
scrCmdListener);
|
||||
resize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this MIDPWindow's displayable to "fullscreen" mode. This
|
||||
* will expand the region occupied by the current displayable to
|
||||
* include the area previously occupied by the title and ticker
|
||||
* if present
|
||||
*
|
||||
* @param onOff true if the displayable should be in fullscreen mode
|
||||
*/
|
||||
public void setFullScreen(boolean onOff) {
|
||||
if (onOff) {
|
||||
setMode(FULL_SCR_MODE);
|
||||
} else {
|
||||
setMode(NORMAL_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current layout
|
||||
*/
|
||||
public void updateLayout() {
|
||||
resize();
|
||||
requestRepaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes layout mode.
|
||||
*
|
||||
* @param mode the mode to be set
|
||||
*/
|
||||
private void setMode(int mode) {
|
||||
screenMode = mode;
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if window is in full screen mode.
|
||||
*
|
||||
* @return true if in full screen mode
|
||||
*/
|
||||
public boolean isInFullScreenMode() {
|
||||
return screenMode == FULL_SCR_MODE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called to paint a wash over the background of this window.
|
||||
* Used by SoftButtonLayer when the system menu pops up, and
|
||||
* internally when an Alert is shown.
|
||||
*
|
||||
* @param onOff A flag indicating if the wash should be on or off
|
||||
*/
|
||||
public void paintWash(boolean onOff) {
|
||||
if (alertLayer.visible) {
|
||||
addLayer(washLayer);
|
||||
if (onOff) {
|
||||
addLayer(alertWashLayer);
|
||||
} else {
|
||||
removeLayer(alertWashLayer);
|
||||
|
||||
tickerLayer.addDirtyRegion();
|
||||
alertLayer.addDirtyRegion();
|
||||
}
|
||||
} else {
|
||||
removeLayer(alertWashLayer);
|
||||
if (onOff) {
|
||||
addLayer(washLayer);
|
||||
} else {
|
||||
removeLayer(washLayer);
|
||||
|
||||
tickerLayer.addDirtyRegion();
|
||||
titleLayer.addDirtyRegion();
|
||||
|
||||
if (ptiLayer != null) {
|
||||
ptiLayer.addDirtyRegion();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the left soft button (one).
|
||||
*
|
||||
* @return the command that's tied to the left soft button
|
||||
*/
|
||||
public Command getSoftOne() {
|
||||
return buttonLayer.getSoftOne();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command array tied to the right soft button (two).
|
||||
*
|
||||
* @return the command array that's tied to the right soft button
|
||||
*/
|
||||
public Command[] getSoftTwo() {
|
||||
return buttonLayer.getSoftTwo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by soft button layer when interactive state of it
|
||||
* has been changed
|
||||
*
|
||||
* @param interactive if soft buttons are currently interactive.
|
||||
*/
|
||||
public void onSoftButtonInteractive(boolean interactive) {
|
||||
if (FULL_SCR_MODE == screenMode) {
|
||||
// IMPL NOTES: in full screen mode we hide/show soft button layer
|
||||
// depending on its interactiveness, so we should update layout
|
||||
updateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the point lies in the bounds of commnad layer
|
||||
* @param x the "x" coordinate of the point
|
||||
* @param y the "y" coordinate of the point
|
||||
* @return true if the point lies in the bounds of commnad layer
|
||||
*/
|
||||
public boolean belongToCmdLayers(int x, int y) {
|
||||
return buttonLayer.belongToCmdLayers(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current vertical scroll position and proportion.
|
||||
*
|
||||
* @param scrollPosition vertical scroll position.
|
||||
* @param scrollProportion vertical scroll proportion.
|
||||
* @return true if set vertical scroll occues
|
||||
*/
|
||||
public boolean setVerticalScroll(int scrollPosition, int scrollProportion) {
|
||||
|
||||
BodyLayer layer = null;
|
||||
if (alertLayer.isVisible()) {
|
||||
layer = alertLayer;
|
||||
} else if (bodyLayer.isVisible()) {
|
||||
layer = bodyLayer;
|
||||
}
|
||||
|
||||
if (layer != null && layer.setVerticalScroll(scrollPosition, scrollProportion)) {
|
||||
setDirty();
|
||||
sizeChangedOccured = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current x anchor coordinate for the body layer (the body
|
||||
* layer renders the contents of the current displayable).
|
||||
*
|
||||
* @return the x anchor coordinate of the body layer
|
||||
*/
|
||||
public int getBodyAnchorX() {
|
||||
return bodyLayer.bounds[X];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current y anchor coordinate for the body layer (the body
|
||||
* layer renders the contents of the current displayable).
|
||||
*
|
||||
* @return the y anchor coordinate of the body layer
|
||||
*/
|
||||
public int getBodyAnchorY() {
|
||||
return bodyLayer.bounds[Y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current x anchor coordinate for the alert layer (the body
|
||||
* layer renders the contents of the current displayable).
|
||||
*
|
||||
* @return the x anchor coordinate of the alert layer
|
||||
*/
|
||||
public int getAlertAnchorX() {
|
||||
return alertLayer.bounds[X];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current y anchor coordinate for the alert layer (the body
|
||||
* layer renders the contents of the current displayable).
|
||||
*
|
||||
* @return the y anchor coordinate of the alert layer
|
||||
*/
|
||||
public int getAlertAnchorY() {
|
||||
return alertLayer.bounds[Y];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current width of the body layer (the body
|
||||
* layer renders the contents of the current displayable).
|
||||
*
|
||||
* @return the width of the body layer
|
||||
*/
|
||||
public int getBodyWidth() {
|
||||
return bodyLayer.bounds[W];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current height of the body layer (the body
|
||||
* layer renders the contents of the current displayable).
|
||||
*
|
||||
* @return the height of the body layer
|
||||
*/
|
||||
public int getBodyHeight() {
|
||||
return bodyLayer.bounds[H];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the width of some default Body layer wich is still not rendered on the screen
|
||||
* depending on the screen mode and the layers attached to the screen
|
||||
* @param width screen width
|
||||
* @param isFullScn true if the full scren is set for the body layer
|
||||
* @param scrollBarIsVisible true if the scroll bar is in use for the body layer
|
||||
* @return width of the paticular body layer
|
||||
*/
|
||||
public static int getDefaultBodyWidth(int width,
|
||||
boolean isFullScn,
|
||||
boolean scrollBarIsVisible) {
|
||||
int w = width;
|
||||
// TODO: scroll arrows (bar? ) indicator has to be hidden?
|
||||
if (scrollBarIsVisible) {
|
||||
w -= ScrollIndSkin.WIDTH;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the height of some default Body layer wich is still not rendered on the screen
|
||||
* depending on the screen mode and the layers attached to the screen
|
||||
* param height scren height
|
||||
* @param isFullScn true if the full scren is set for the body layer
|
||||
* @param titleIsVisible true if the title is attached
|
||||
* @param tickerIsVisible true if the ticker is attached
|
||||
* @param softBtnLayerIsVisible true if command layer is visible
|
||||
* @return height of the paticular body layer
|
||||
*/
|
||||
public static int getDefaultBodyHeight(int height,
|
||||
boolean isFullScn,
|
||||
boolean titleIsVisible,
|
||||
boolean tickerIsVisible,
|
||||
boolean softBtnLayerIsVisible) {
|
||||
int h = height;
|
||||
if (!isFullScn) {
|
||||
if (titleIsVisible) {
|
||||
h -= TitleSkin.HEIGHT;
|
||||
}
|
||||
if (tickerIsVisible) {
|
||||
h -= TickerSkin.HEIGHT;
|
||||
}
|
||||
if (softBtnLayerIsVisible) {
|
||||
h -= SoftButtonSkin.HEIGHT;
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current width of the alert layer (the body
|
||||
* layer renders the contents of the current displayable).
|
||||
*
|
||||
* @return the width of the alert layer
|
||||
*/
|
||||
public int getAlertWidth() {
|
||||
return alertLayer.bounds[W];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current height of the alert layer (the body
|
||||
* layer renders the contents of the current displayable).
|
||||
*
|
||||
* @return the height of the alert layer
|
||||
*/
|
||||
public int getAlertHeight() {
|
||||
return alertLayer.bounds[H];
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to determine if the given point lies within
|
||||
* the bounds of body layer. The point should be in the coordinate
|
||||
* space of this layer's containing CWindow.
|
||||
*
|
||||
* @param x the "x" coordinate of the point
|
||||
* @param y the "y" coordinate of the point
|
||||
* @return true if the coordinate lies in the bounds of this layer
|
||||
*/
|
||||
public boolean bodyContainsPoint(int x, int y) {
|
||||
return bodyLayer.containsPoint(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* MIDPWindow overrides the parent paint method in order to
|
||||
* do special effects such as paint a "wash" over the background
|
||||
* when a dialog is up. Also in an effort to call
|
||||
* {@link javax.microedition.lcdui.Displayable#sizeChanged }
|
||||
* method before painting. This implementation determine whether size
|
||||
* has been changed and calls <code>sizeChanged()</code> if it's so.
|
||||
* Anyway it invokes the base class's {@link CWindow#paint} method.
|
||||
*
|
||||
* @param g The graphics object to use to paint this MIDP window.
|
||||
* @param refreshQ The chameleon graphics queue.
|
||||
*/
|
||||
public void callPaint(Graphics g, CGraphicsQ refreshQ) {
|
||||
if (sizeChangedOccured) {
|
||||
if (tunnel != null) {
|
||||
int w = getBodyWidth();
|
||||
int h = getBodyHeight();
|
||||
tunnel.callSizeChanged(w, h);
|
||||
sizeChangedOccured = false;
|
||||
}
|
||||
}
|
||||
super.paint(g, refreshQ);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is an optimization which allows Display to bypass
|
||||
* the Chameleon paint engine logic and directly paint an animating
|
||||
* canvas. Display will call this method with the graphics context
|
||||
* and this method will either return false, indicating the Chameleon
|
||||
* paint engine should not be bypassed, or will return true and will
|
||||
* setup the graphics context for the canvas to be painted directly.
|
||||
*
|
||||
* @param g the graphics context to setup
|
||||
* @return true if Chameleon's paint logic can be bypassed and the
|
||||
* canvas can be rendered directly.
|
||||
*/
|
||||
public boolean setGraphicsForCanvas(Graphics g) {
|
||||
// IMPL_NOTE: Only Canvas painting specially doesn't change dirty
|
||||
// state of the owner window, however it is not enough to bypass
|
||||
// the Chameleon paint engine. Body layer holding the Canvas
|
||||
// should be not overlapped by a visible layer also.
|
||||
if (super.dirty) {
|
||||
// Schedule next overlapping check
|
||||
bodyChecked = false;
|
||||
return false;
|
||||
}
|
||||
if (!bodyChecked) {
|
||||
bodyOverlapped = !bodyLayer.opaque ||
|
||||
isOverlapped(bodyLayer);
|
||||
bodyChecked = true;
|
||||
}
|
||||
if (!bodyOverlapped) {
|
||||
bodyLayer.setGraphicsForCanvas(g);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to resize window and its content layers
|
||||
* according to a size changes in the loaded skins.
|
||||
* This is important to re-calculate whenever things such as
|
||||
* titles, tickers, fullscreen mode, etc. change state.
|
||||
*/
|
||||
public void resize() {
|
||||
super.resize(tunnel.getDisplayWidth(), tunnel.getDisplayHeight());
|
||||
|
||||
int oldHeight = bodyLayer.bounds[H];
|
||||
int oldWidth = bodyLayer.bounds[W];
|
||||
switch (screenMode) {
|
||||
case FULL_SCR_MODE:
|
||||
// TODO: scroll arrows (bar? ) indicator has to be hidden?
|
||||
titleLayer.visible = false;
|
||||
tickerLayer.visible = false;
|
||||
buttonLayer.visible =
|
||||
buttonLayer.isInteractive();
|
||||
break;
|
||||
case NORMAL_MODE:
|
||||
titleLayer.visible =
|
||||
(titleLayer.getTitle() != null);
|
||||
tickerLayer.visible =
|
||||
(tickerLayer.getText() != null);
|
||||
buttonLayer.visible = true;
|
||||
break;
|
||||
default:
|
||||
Logging.report(Logging.ERROR, LogChannels.LC_HIGHUI,
|
||||
"MIDPWindow: screenMode=" + screenMode);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < LAST_LAYER; i++) {
|
||||
CLayer l = mainLayers[i];
|
||||
if (l != null && l.visible) {
|
||||
l.update(mainLayers);
|
||||
}
|
||||
}
|
||||
|
||||
if (bodyLayer.bounds[W] != oldWidth ||
|
||||
bodyLayer.bounds[H] != oldHeight) {
|
||||
setDirty();
|
||||
sizeChangedOccured = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to clear all current popups. This occurs if a
|
||||
* change of displayable occurs, as all popups are treated as belonging
|
||||
* to the current displayable.
|
||||
*/
|
||||
protected void clearPopups() {
|
||||
synchronized (super.layers) {
|
||||
for (CLayerElement le = super.layers.getTop();
|
||||
le != null; le = le.getLower()) {
|
||||
CLayer l = le.getLayer();
|
||||
if (l instanceof PopupLayer) {
|
||||
removeLayer(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the "top" most Popup layer added to this body layer.
|
||||
* If there are no popups, this method returns null.
|
||||
*
|
||||
* @return the top most popup layer, or null if there are none.
|
||||
*/
|
||||
public PopupLayer getTopMostPopup() {
|
||||
synchronized (super.layers) {
|
||||
for (CLayerElement le = super.layers.getTop();
|
||||
le != null; le = le.getLower()) {
|
||||
CLayer l = le.getLayer();
|
||||
if (l instanceof PopupLayer) {
|
||||
return (PopupLayer)l;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new layer by id and launch addLayer()
|
||||
* @param id - layer id
|
||||
*/
|
||||
private void createLayer(int id) {
|
||||
switch (id) {
|
||||
case PTI_LAYER:
|
||||
break;
|
||||
case TITLE_LAYER:
|
||||
titleLayer = new TitleLayer();
|
||||
mainLayers[id] = titleLayer;
|
||||
addLayer(titleLayer);
|
||||
break;
|
||||
case TICKER_LAYER:
|
||||
tickerLayer = new TickerLayer();
|
||||
mainLayers[id] = tickerLayer ;
|
||||
break;
|
||||
case BTN_LAYER:
|
||||
buttonLayer = new SoftButtonLayer(tunnel);
|
||||
mainLayers[id] = buttonLayer;
|
||||
addLayer(buttonLayer);
|
||||
break;
|
||||
case ALERT_LAYER:
|
||||
alertLayer = new AlertLayer(tunnel);
|
||||
mainLayers[id] = alertLayer;
|
||||
break;
|
||||
case WASH_LAYER:
|
||||
washLayer = new WashLayer();
|
||||
mainLayers[id] = washLayer;
|
||||
break;
|
||||
case ALERT_WASH_LAYER:
|
||||
alertWashLayer = new WashLayer();
|
||||
mainLayers[id] = alertWashLayer;
|
||||
break;
|
||||
case KEYBOARD_LAYER:
|
||||
break;
|
||||
case BODY_LAYER:
|
||||
bodyLayer = new BodyLayer(tunnel);
|
||||
mainLayers[id] = bodyLayer;
|
||||
addLayer(bodyLayer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -2564,6 +2564,24 @@ public class Display {
|
|||
return (current instanceof AlertLF) ? window.getAlertHeight() : window.getBodyHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the anchor x of the current displayable layer.
|
||||
*
|
||||
* @return the anchor x of the current displayable layer
|
||||
*/
|
||||
public int getDisplayableAnchorX() {
|
||||
return (current instanceof AlertLF) ? window.getAlertAnchorX() : window.getBodyAnchorX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the anchor y of the current displayable layer.
|
||||
*
|
||||
* @return the anchor y of the current displayable layer
|
||||
*/
|
||||
public int getDisplayableAnchorY() {
|
||||
return (current instanceof AlertLF) ? window.getAlertAnchorY() : window.getBodyAnchorY();
|
||||
}
|
||||
|
||||
/** Get the width of some default displayable depending on the screen mode and
|
||||
* the layers attached to the screen
|
||||
* @param isFullScn true if the full screen is set for the displayable
|
||||
|
|
27
libs/fs.js
27
libs/fs.js
|
@ -99,6 +99,7 @@ var fs = (function() {
|
|||
var reader = new FileReader();
|
||||
reader.addEventListener("loadend", function() {
|
||||
var fd = openedFiles.push({
|
||||
dirty: false,
|
||||
path: path,
|
||||
buffer: new FileBuffer(new Uint8Array(reader.result)),
|
||||
position: 0,
|
||||
|
@ -110,11 +111,20 @@ var fs = (function() {
|
|||
});
|
||||
}
|
||||
|
||||
function close(fd) {
|
||||
function close(fd, cb) {
|
||||
if (fd >= 0 && openedFiles[fd]) {
|
||||
// Replace descriptor object with null value instead of removing it from
|
||||
// the array so we don't change the indexes of the other objects.
|
||||
openedFiles.splice(fd, 1, null);
|
||||
flush(fd, function() {
|
||||
// Replace descriptor object with null value instead of removing it from
|
||||
// the array so we don't change the indexes of the other objects.
|
||||
openedFiles.splice(fd, 1, null);
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +170,7 @@ var fs = (function() {
|
|||
|
||||
openedFiles[fd].position = from + data.byteLength;
|
||||
openedFiles[fd].stat = { mtime: Date.now(), isDir: false };
|
||||
openedFiles[fd].dirty = true;
|
||||
}
|
||||
|
||||
function getpos(fd) {
|
||||
|
@ -179,8 +190,15 @@ var fs = (function() {
|
|||
}
|
||||
|
||||
function flush(fd, cb) {
|
||||
// Bail early if the file has not been modified.
|
||||
if (!openedFiles[fd].dirty) {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
var blob = new Blob([openedFiles[fd].buffer.getContent()]);
|
||||
asyncStorage.setItem(openedFiles[fd].path, blob, function() {
|
||||
openedFiles[fd].dirty = false;
|
||||
if (openedFiles[fd].stat) {
|
||||
setStat(openedFiles[fd].path, openedFiles[fd].stat, cb);
|
||||
} else {
|
||||
|
@ -228,6 +246,7 @@ var fs = (function() {
|
|||
if (size != openedFiles[fd].buffer.contentSize) {
|
||||
openedFiles[fd].buffer.setSize(size);
|
||||
openedFiles[fd].stat = { mtime: Date.now(), isDir: false };
|
||||
openedFiles[fd].dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
7
main.js
7
main.js
|
@ -41,7 +41,12 @@ if ("gamepad" in urlParams && !/no|0/.test(urlParams.gamepad)) {
|
|||
document.documentElement.classList.add('gamepad');
|
||||
}
|
||||
|
||||
var jars = ["java/classes.jar", "tests/tests.jar"];
|
||||
var jars = ["java/classes.jar"];
|
||||
|
||||
if (MIDP.midletClassName == "RunTests") {
|
||||
jars.push("tests/tests.jar");
|
||||
}
|
||||
|
||||
if (urlParams.jars) {
|
||||
jars = jars.concat(urlParams.jars.split(":"));
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"name": "j2me.js",
|
||||
"description": "j2me interpreter for firefox os",
|
||||
"launch_path": "/index.html?autosize=1&logConsole=web",
|
||||
"origin": "app://j2mejs.mozilla.org",
|
||||
"icons": {
|
||||
"128": "/img/icon-128.png"
|
||||
},
|
||||
|
|
25
midp/fs.js
25
midp/fs.js
|
@ -116,10 +116,7 @@ Native.create("com/sun/midp/rms/RecordStoreFile.commitWrite.(I)V", function(hand
|
|||
|
||||
Native.create("com/sun/midp/rms/RecordStoreFile.closeFile.(I)V", function(handle) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
fs.flush(handle, function() {
|
||||
fs.close(handle);
|
||||
resolve();
|
||||
});
|
||||
fs.close(handle, resolve);
|
||||
});
|
||||
}, true);
|
||||
|
||||
|
@ -445,10 +442,7 @@ Native.create("com/ibm/oti/connection/file/Connection.truncateImpl.([BJ)V", func
|
|||
}
|
||||
|
||||
fs.ftruncate(fd, newLength.toNumber());
|
||||
fs.flush(fd, function() {
|
||||
fs.close(fd);
|
||||
resolve();
|
||||
});
|
||||
fs.close(fd, resolve);
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
|
@ -507,15 +501,7 @@ Native.create("com/ibm/oti/connection/file/FCInputStream.closeImpl.(I)V", functi
|
|||
|
||||
Native.create("com/ibm/oti/connection/file/FCOutputStream.closeImpl.(I)V", function(fd) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (fd <= -1) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
fs.flush(fd, function() {
|
||||
fs.close(fd);
|
||||
resolve();
|
||||
});
|
||||
fs.close(fd, resolve);
|
||||
});
|
||||
}, true);
|
||||
|
||||
|
@ -665,9 +651,6 @@ Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.sizeOf.(I)I", fun
|
|||
|
||||
Native.create("com/sun/midp/io/j2me/storage/RandomAccessStream.close.(I)V", function(handle) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
fs.flush(handle, function() {
|
||||
fs.close(handle);
|
||||
resolve();
|
||||
});
|
||||
fs.close(handle, resolve);
|
||||
});
|
||||
}, true);
|
||||
|
|
|
@ -950,7 +950,7 @@
|
|||
return parseInt(this.textEditor.style.height);
|
||||
});
|
||||
|
||||
Native.create("com/nokia/mid/ui/CanvasItem.setPosition.(II)V", function(x, y) {
|
||||
Native.create("com/nokia/mid/ui/CanvasItem.setPosition0.(II)V", function(x, y) {
|
||||
this.textEditor.style.left = x + "px";
|
||||
this.textEditor.style.top = y + "px";
|
||||
});
|
||||
|
|
|
@ -593,8 +593,8 @@ NokiaImageProcessingLocalMsgConnection.prototype.sendMessageToServer = function(
|
|||
var aspect = decoder.getValue(DataType.STRING);
|
||||
var quality = decoder.getValue(DataType.BYTE);
|
||||
|
||||
if (aspect != "FullImage") {
|
||||
console.error("(nokia.image-processing) event " + name + " with aspect != 'FullImage' not implemented " +
|
||||
if (aspect != "FullImage" && aspect != "LockToPartialView") {
|
||||
console.error("(nokia.image-processing) event " + name + " with aspect != 'FullImage' or 'LockToPartialView' not implemented " +
|
||||
util.decodeUtf8(new Uint8Array(message.data.buffer, message.offset, message.length)));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ casper.test.begin("unit tests", 7 + gfxTests.length, function(test) {
|
|||
});
|
||||
|
||||
casper
|
||||
.thenOpen("http://localhost:8000/index.html?main=com/sun/midp/main/MIDletSuiteLoader&midletClassName=tests/alarm/MIDlet1&jad=tests/midlets/alarm/alarm.jad")
|
||||
.thenOpen("http://localhost:8000/index.html?main=com/sun/midp/main/MIDletSuiteLoader&midletClassName=tests/alarm/MIDlet1&jad=tests/midlets/alarm/alarm.jad&jars=tests/tests.jar")
|
||||
.withFrame(0, function() {
|
||||
casper.waitForText("Hello World from MIDlet2", function() {
|
||||
test.pass();
|
||||
|
@ -79,11 +79,11 @@ casper.test.begin("unit tests", 7 + gfxTests.length, function(test) {
|
|||
casper
|
||||
.thenOpen("http://localhost:8000/tests/fstests.html")
|
||||
.waitForText("DONE", function() {
|
||||
test.assertTextExists("DONE: 124 PASS, 0 FAIL", "run fs.js unit tests");
|
||||
test.assertTextExists("DONE: 126 PASS, 0 FAIL", "run fs.js unit tests");
|
||||
});
|
||||
|
||||
casper
|
||||
.thenOpen("http://localhost:8000/index.html?midletClassName=tests.sms.SMSMIDlet&main=com/sun/midp/main/MIDletSuiteLoader")
|
||||
.thenOpen("http://localhost:8000/index.html?midletClassName=tests.sms.SMSMIDlet&main=com/sun/midp/main/MIDletSuiteLoader&jars=tests/tests.jar")
|
||||
.withFrame(0, function() {
|
||||
this.waitForText("START", function() {
|
||||
this.evaluate(function() {
|
||||
|
@ -100,7 +100,7 @@ casper.test.begin("unit tests", 7 + gfxTests.length, function(test) {
|
|||
});
|
||||
|
||||
casper
|
||||
.thenOpen("http://localhost:8000/index.html?midletClassName=tests.fileui.FileUIMIDlet")
|
||||
.thenOpen("http://localhost:8000/index.html?midletClassName=tests.fileui.FileUIMIDlet&jars=tests/tests.jar")
|
||||
.withFrame(0, function() {
|
||||
this.waitForText("START", function() {
|
||||
this.waitUntilVisible(".nokia-fileui-prompt", function() {
|
||||
|
@ -127,7 +127,7 @@ casper.test.begin("unit tests", 7 + gfxTests.length, function(test) {
|
|||
|
||||
gfxTests.forEach(function(testCase) {
|
||||
casper
|
||||
.thenOpen("http://localhost:8000/index.html?main=com/sun/midp/main/MIDletSuiteLoader&midletClassName=" + testCase.name)
|
||||
.thenOpen("http://localhost:8000/index.html?main=com/sun/midp/main/MIDletSuiteLoader&midletClassName=" + testCase.name + "&jars=tests/tests.jar")
|
||||
.withFrame(0, function() {
|
||||
casper.waitForText("PAINTED", function() {
|
||||
this.waitForSelector("#canvas", function() {
|
||||
|
|
|
@ -556,7 +556,7 @@ tests.push(function() {
|
|||
|
||||
tests.push(function() {
|
||||
fs.size("/tmp/tmp.txt", function(size) {
|
||||
is(size, 12, "file's size is 12");
|
||||
is(size, 131079, "file's size after closing is 131079");
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
@ -676,6 +676,18 @@ tests.push(function() {
|
|||
}, 1);
|
||||
});
|
||||
|
||||
tests.push(function() {
|
||||
window.setTimeout(function() {
|
||||
fs.flush(fd, function() {
|
||||
fs.stat("/tmp/stat.txt", function(stat) {
|
||||
is(stat.mtime, lastTime, "flush on just opened file doesn't update mtime");
|
||||
lastTime = stat.mtime;
|
||||
next();
|
||||
});
|
||||
});
|
||||
}, 1);
|
||||
});
|
||||
|
||||
tests.push(function() {
|
||||
window.setTimeout(function() {
|
||||
fs.write(fd, new TextEncoder().encode("mi"));
|
||||
|
@ -700,6 +712,18 @@ tests.push(function() {
|
|||
}, 1);
|
||||
});
|
||||
|
||||
tests.push(function() {
|
||||
window.setTimeout(function() {
|
||||
fs.flush(fd, function() {
|
||||
fs.stat("/tmp/stat.txt", function(stat) {
|
||||
is(stat.mtime, lastTime, "flush on non-dirty file doesn't change mtime");
|
||||
lastTime = stat.mtime;
|
||||
next();
|
||||
});
|
||||
});
|
||||
}, 1);
|
||||
});
|
||||
|
||||
tests.push(function() {
|
||||
window.setTimeout(function() {
|
||||
fs.ftruncate(fd, 4);
|
||||
|
|
|
@ -14,5 +14,5 @@ port = 8000
|
|||
if len(sys.argv) > 1:
|
||||
port = int(sys.argv[1])
|
||||
|
||||
httpd = BaseHTTPServer.HTTPServer(('localhost', port), CustomRequestHandler)
|
||||
httpd = BaseHTTPServer.HTTPServer(('', port), CustomRequestHandler)
|
||||
httpd.serve_forever()
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
DIR=`mktemp -d -t explode`
|
||||
PWD=`pwd`
|
||||
IN_FILE=$PWD/$1
|
||||
OUT_FILE=$PWD/$2
|
||||
|
||||
echo "DIR: $DIR"
|
||||
echo "IN_FILE: $IN_FILE"
|
||||
echo "OUT_FILE: $OUT_FILE"
|
||||
|
||||
pushd $DIR
|
||||
jar xf $IN_FILE
|
||||
jar cfM0 $OUT_FILE *
|
||||
popd
|
||||
|
||||
rm -rf "$DIR"
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env bash
|
||||
# This sets up a directory suitable for use as WebApp. It is expected to be
|
||||
# run from your root j2me.js checkout after you've run |make test|.
|
||||
# NB: I'm making no effort for this to be efficient or clever.
|
||||
|
||||
PACKAGE_DIR="output"
|
||||
|
||||
rm -rf $PACKAGE_DIR/
|
||||
mkdir $PACKAGE_DIR
|
||||
|
||||
# setup the root
|
||||
cp *.js *.html *.webapp $PACKAGE_DIR/.
|
||||
|
||||
# copy over jars/jads that are used for the webapp
|
||||
# NB: we could be smart about this and parse the manifest, patches welcome!
|
||||
# grep 'launch_path' manifest.webapp | sed -E 's/.*jars=([^&]+)&.*$/\1/'
|
||||
cp *.jar *.jad $PACKAGE_DIR/.
|
||||
|
||||
# setup java dir
|
||||
mkdir $PACKAGE_DIR/java
|
||||
cp java/*.jar $PACKAGE_DIR/java
|
||||
|
||||
# copy entire certs dir, it's possible we just need the ks files
|
||||
cp -R certs $PACKAGE_DIR/.
|
||||
|
||||
# copy entire classfile dir
|
||||
cp -R classfile $PACKAGE_DIR/.
|
||||
|
||||
# copy entire contents of libs dir
|
||||
cp -R libs $PACKAGE_DIR/.
|
||||
|
||||
# copy entire contents of midp dir
|
||||
cp -R midp $PACKAGE_DIR/.
|
||||
|
||||
# copy entire contents of style dir
|
||||
cp -R style $PACKAGE_DIR/.
|
||||
|
||||
# setup tests dir, for now just the jar and js files
|
||||
mkdir $PACKAGE_DIR/tests
|
||||
cp tests/tests.jar $PACKAGE_DIR/tests/.
|
||||
cp tests/*.js $PACKAGE_DIR/tests/.
|
||||
|
Загрузка…
Ссылка в новой задаче