javauis/lcdui_qt/src/javax/microedition/lcdui/Buffer.java
changeset 35 85266cc22c7f
parent 26 dc7c549001d5
child 47 f40128debb5d
equal deleted inserted replaced
26:dc7c549001d5 35:85266cc22c7f
     1 /*
     1 /*
     2 * Copyright (c) 2009,2010 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    12 * Contributors:
    12 * Contributors:
    13 *
    13 *
    14 * Description:
    14 * Description:
    15 *
    15 *
    16 */
    16 */
       
    17 
    17 package javax.microedition.lcdui;
    18 package javax.microedition.lcdui;
    18 
    19 
    19 import org.eclipse.swt.widgets.Control;
    20 import org.eclipse.swt.widgets.Control;
       
    21 import org.eclipse.swt.widgets.Widget;
    20 import org.eclipse.swt.graphics.Point;
    22 import org.eclipse.swt.graphics.Point;
    21 import org.eclipse.swt.graphics.Rectangle;
    23 import org.eclipse.swt.graphics.Rectangle;
       
    24 import org.eclipse.swt.internal.qt.OS;
    22 import org.eclipse.swt.internal.qt.graphics.GraphicsContext;
    25 import org.eclipse.swt.internal.qt.graphics.GraphicsContext;
    23 import org.eclipse.swt.internal.qt.graphics.JavaCommandBuffer;
    26 import org.eclipse.swt.internal.qt.graphics.JavaCommandBuffer;
    24 import org.eclipse.swt.internal.qt.graphics.WindowSurface;
    27 import org.eclipse.swt.internal.qt.graphics.WindowSurface;
    25 
    28 
    26 /**
    29 /**
    38  */
    41  */
    39 
    42 
    40 abstract class Buffer
    43 abstract class Buffer
    41 {
    44 {
    42 
    45 
       
    46     // Default values for Graphics 
       
    47     final static Font defaultFont = Font.getDefaultFont();
       
    48     final static int defaultColor = 0xff000000;
       
    49     final static int defaultStrokeStyle = Graphics.SOLID;
       
    50     final static int defaultTranslateX = 0;
       
    51     final static int defaultTranslateY = 0;
       
    52 
    43     // Constants for buffer host types
    53     // Constants for buffer host types
    44     final static int HOST_TYPE_IMAGE = 1;
    54     final static int HOST_TYPE_IMAGE = 1;
    45     final static int HOST_TYPE_CANVAS = 2;
    55     final static int HOST_TYPE_CANVAS = 2;
    46     final static int HOST_TYPE_CUSTOMITEM = 3;
    56     final static int HOST_TYPE_CUSTOMITEM = 3;
    47 
    57 
    66 
    76 
    67     private GraphicsContext gc;
    77     private GraphicsContext gc;
    68     private JavaCommandBuffer commandBuffer;
    78     private JavaCommandBuffer commandBuffer;
    69     private Rectangle hostBounds;
    79     private Rectangle hostBounds;
    70     private Graphics currentClient;
    80     private Graphics currentClient;
    71     private boolean started;
    81     private boolean isInitialized;
    72     private int clientCount;
    82     private int clientCount;
    73 
    83     
    74     // The target window surface where this
    84     private boolean isSurfaceSessionOpen;
    75     // instance flushes draw primitives
       
    76     WindowSurface windowSurface;
       
    77 
    85 
    78     /**
    86     /**
    79      * Constructor
    87      * Constructor
    80      */
    88      */
    81     protected Buffer()
    89     protected Buffer()
    88         bufferTranslateX = 0;
    96         bufferTranslateX = 0;
    89         bufferTranslateY = 0;
    97         bufferTranslateY = 0;
    90     }
    98     }
    91 
    99 
    92     /**
   100     /**
       
   101      * Creates Buffer instance based on the type of given host object 
       
   102      * and the platform (symbian/linux) currently running on.
       
   103      * 
       
   104      * @param host The host target where pixels are drawn. Given object must be Canvas, CustomItem or Image.
       
   105      * @param control The eSWT control associated with the target, or null if the host is Image
       
   106      * @return New buffer instance
       
   107      */
       
   108     static Buffer createInstance(Object host, Control control)
       
   109     {
       
   110     	if(host instanceof Canvas) 
       
   111     	{
       
   112     		if(OS.windowServer == OS.WS_SYMBIAN_S60)
       
   113     		{	
       
   114     		    return new CanvasBufferSymbian((Canvas) host, control);
       
   115     		}
       
   116     		else if(OS.windowServer == OS.WS_X11)
       
   117     		{
       
   118     			return new CanvasBufferLinux((Canvas) host, control);
       
   119     		}
       
   120   			return null;
       
   121     	} 
       
   122     	else if(host instanceof CustomItem)
       
   123     	{
       
   124     		if(OS.windowServer == OS.WS_SYMBIAN_S60)
       
   125     		{	
       
   126     		    return new CustomItemBufferSymbian((CustomItem) host, control);
       
   127     		}
       
   128     		else if(OS.windowServer == OS.WS_X11)
       
   129     		{
       
   130     			return new CustomItemBufferLinux((CustomItem) host, control);
       
   131     		}
       
   132   			return null;
       
   133     	} 
       
   134     	else if(host instanceof Image) 
       
   135     	{
       
   136     	    return new ImageBuffer((Image) host);	
       
   137     	}
       
   138     	return null;
       
   139     }
       
   140     
       
   141     /**
    93      * Initializes data, called once
   142      * Initializes data, called once
    94      */
   143      */
    95     void init()
   144     protected void init()
    96     {
   145     {
    97         clientCount = 0;
   146         clientCount = 0;
    98         gc = new GraphicsContext();
   147         gc = new GraphicsContext();
    99         commandBuffer = new JavaCommandBuffer();
   148         commandBuffer = new JavaCommandBuffer();
   100         gc.bindTarget(commandBuffer);
   149         gc.bindTarget(commandBuffer);
   101         writeControlBoundsToBuffer(false);
   150         writeControlBoundsToBuffer(false);
   102         started = true;
   151         isInitialized = true;
   103     }
   152     }
   104 
   153 
   105     /**
   154     /**
   106      * Defines the bounds of the host.
   155      * Defines the bounds of the host.
   107      * Bounds are used for restricting the rendering in
   156      * Bounds are used for restricting the rendering in
   111      * @param crtl The Control of the host
   160      * @param crtl The Control of the host
   112      * @param clienArea The area of the control which can be drawn by Graphics
   161      * @param clienArea The area of the control which can be drawn by Graphics
   113      */
   162      */
   114     void setControlBounds(final Control control)
   163     void setControlBounds(final Control control)
   115     {
   164     {
   116         ESWTUIThreadRunner.safeSyncExec(new Runnable()
   165         // This implementation is based on the fact that
   117         {
   166         // the QWindowSurface has the size of the shell active area
   118             public void run()
   167         // not the whole display, thus Shell clientArea equals QWindowSurface.
   119             {
   168         // This might change in future if/when Qt starts
   120                 // This implementation is based on the fact that
   169         // rendering e.g. the status pane i.e. the whole display
   121                 // the QWindowSurface has the size of the shell active area
   170         // to window surface
   122                 // not the whole display, thus Shell clientArea equals QWindowSurface.
   171         Point controlLoc = control.toDisplay(0,0);
   123                 // This might change in future if/when Qt starts
   172         Point shellLoc = control.getShell().toDisplay(0,0);
   124                 // rendering e.g. the status pane i.e. the whole display
   173         hostBounds.x = controlLoc.x - shellLoc.x;
   125                 // to window surface
   174         hostBounds.y = controlLoc.y - shellLoc.y;
   126                 Point controlLoc = control.toDisplay(0,0);
   175         hostBounds.width = control.getBounds().width;
   127                 Point shellLoc = control.getShell().toDisplay(0,0);
   176         hostBounds.height = control.getBounds().height;
   128                 hostBounds.x = controlLoc.x - shellLoc.x;
   177     }
   129                 hostBounds.y = controlLoc.y - shellLoc.y;
   178 
   130                 hostBounds.width = control.getBounds().width;
   179     /**
   131                 hostBounds.height = control.getBounds().height;
   180      * Prepares surface for a new frame and starts paint session. 
   132             }
   181      * Must be called in UI thread (sync calls this automatically)
   133         });
   182      * and at the start of new frame. The rectangle provided as 
   134     }
   183      * arguments are in control coordinates.
   135 
   184      * 
   136     /**
   185      * @param x The x-coordinate of the area to be painted
   137      * Performs binding to target in host specific way
   186      * @param y The y-coordinate of the area to be painted
       
   187      * @param w The width of the area to be painted
       
   188      * @param h The height of the area to be painted
       
   189      */
       
   190     void startFrame(int x, int y, int w, int h)
       
   191     {
       
   192     	if(!isSurfaceSessionOpen)
       
   193     	{
       
   194     	    beginPaint(x, y, w, h);
       
   195     	    isSurfaceSessionOpen = true;
       
   196     	}
       
   197     }
       
   198     
       
   199     /**
       
   200      * Ends frame painting session. Must be called in UI thread and
       
   201      * at the end of the frame. BlitToDisplay calls this automatically.
       
   202      */
       
   203     void endFrame()
       
   204     {
       
   205     	if(isSurfaceSessionOpen)
       
   206     	{
       
   207     		endPaint();
       
   208     	    isSurfaceSessionOpen = false;
       
   209     	}
       
   210     }
       
   211     
       
   212     /**
       
   213      * Transfers the result of rendering to display.
       
   214      * @param gc The graphics context used for blit, may be null in some cases
       
   215      * @param widget The widget that is the target 
       
   216      */
       
   217     void blitToDisplay(GraphicsContext gc, Widget widget)
       
   218     {
       
   219   	    endFrame();
       
   220     	blit(gc, widget);
       
   221     }
       
   222     
       
   223     /** 
       
   224      * Prepares surface for painting, implemented by
       
   225      * child implementation.
       
   226      * @param x The x-coordinate of the area to be painted
       
   227      * @param y The y-coordinate of the area to be painted
       
   228      * @param w The width of the area to be painted
       
   229      * @param h The height of the area to be painted
       
   230      */
       
   231     abstract void beginPaint(int x, int y, int w, int h);
       
   232     
       
   233     /**
       
   234      * Ends frame painting session. Must be called in UI thread and
       
   235      * at the end of the frame. Implemented by
       
   236      * child implementation.
       
   237      */
       
   238     abstract void endPaint();
       
   239     
       
   240     /**
       
   241      * Performs binding to target in host specific way. Implemented by
       
   242      * child implementation.
   138      */
   243      */
   139     abstract void bindToHost(GraphicsContext gc);
   244     abstract void bindToHost(GraphicsContext gc);
   140 
   245     
   141     /**
   246     /** 
   142      * Getter for the host of the buffer
   247      * Performs the actual blit operation in child class implementation.
       
   248      * @param gc The graphics context used for blit, may be null in some cases
       
   249      * @param widget The widget that is the target 
       
   250      */
       
   251     abstract void blit(GraphicsContext gc, Widget widget);
       
   252     
       
   253     /**
       
   254      * Getter for the host of the buffer, implemented by
       
   255      * child implementation.
   143      * @return The host
   256      * @return The host
   144      */
   257      */
   145     abstract Object getHost();
   258     abstract Object getHost();
   146 
   259 
   147     /**
   260     /**
   148      * Getter for the host type
   261      * Getter for the host type,implemented by
       
   262      * child implementation.
   149      * @return One of host types defined in this class
   263      * @return One of host types defined in this class
   150      */
   264      */
   151     abstract int getHostType();
   265     abstract int getHostType();
   152 
   266 
   153     /**
   267     /**
   154      *  Setups the window surface if not setup already.
   268      * Status checker that indicates if this instance has requested a synchronous paint event, 
   155      *  This method must be called before flushing buffer to
   269      * implemented by child implementation.
   156      *  window surface
   270      * @return True if this instance has requested a redraw paint event, otherwise false
   157      *  Note. must be called in UI thread
   271      */
   158      */
   272     abstract boolean isPaintingActive(); 
   159     abstract void setupWindowSurface();
   273     
   160 
       
   161     /**
   274     /**
   162      * Creates and returns new Graphics instance
   275      * Creates and returns new Graphics instance
   163      * @return new Graphics instance
   276      * @return new Graphics instance
   164      */
   277      */
   165     Graphics getGraphics()
   278     Graphics getGraphics()
   166     {
   279     {
   167         if(!started)
   280         if(!isInitialized)
   168         {
   281         {
   169             init();
   282             init();
   170         }
   283         }
   171         clientCount++;
   284         clientCount++;
   172         return new Graphics(this);
   285         // In case this is the first Graphics instance
       
   286         // write the default values to the buffer
       
   287         if(clientCount == 1) 
       
   288         {
       
   289             writeDefaultValuesToBuffer();	
       
   290         }
       
   291         return new Graphics(this, hostBounds );
   173     }
   292     }
   174 
   293 
   175     /**
   294     /**
   176      * Synchronizes this buffer with the actual target
   295      * Synchronizes this buffer with the actual target
   177      * must be called in UI thread. If no Graphics instances
   296      * must be called in UI thread. If no Graphics instances
   178      * are creates, sync has no effect
   297      * are created, sync has no effect. This variant always closes 
   179      */
   298      * the surface session unconditionally
   180     void sync()
   299      */
   181     {
   300     void sync() 
   182         if(!started)
   301     {
   183         {
   302     	sync(true);
   184             return;
   303     }
   185         }
   304     
       
   305     /**
       
   306      * Synchronizes this buffer with the actual target
       
   307      * must be called in UI thread. If no Graphics instances
       
   308      * are created, sync has no effect
       
   309      * 
       
   310      * @param closeSurfaceSession If true the endFrame is called after sync has been 
       
   311      *                            performed closing the surface session, otherwise
       
   312      *                            endFrame is performed and surface session is left open
       
   313      */
       
   314     void sync(boolean closeSurfaceSession)
       
   315     {
       
   316         if(!isInitialized)
       
   317         {
       
   318             return;
       
   319         }
       
   320         
   186         // if there's nothing to flush return
   321         // if there's nothing to flush return
   187         if(!commandBuffer.containsDrawnPrimitives())
   322         if(!commandBuffer.containsDrawnPrimitives())
   188         {
   323         {
   189             return;
   324             return;
   190         }
   325         }
       
   326         
       
   327         // Start surface session if not started yet
       
   328        	startFrame(hostBounds.x, hostBounds.y , hostBounds.width , hostBounds.height);
       
   329         
   191         doRelease();
   330         doRelease();
   192         bindToHost(gc);
   331         bindToHost(gc);
   193         gc.render(commandBuffer);
   332         gc.render(commandBuffer);
   194         doRelease();
   333         doRelease();
   195 
   334 
       
   335         // Close surface session
       
   336         if(closeSurfaceSession)
       
   337         {
       
   338             endFrame();
       
   339         }
       
   340         
   196         // Reset commands
   341         // Reset commands
   197         commandBuffer.reset();
   342         commandBuffer.reset();
   198 
   343 
   199         // Write last settings to buffer
   344         // Write last settings to buffer
   200         // as they are reset in bind
   345         // as they are reset in bind
   218     /**
   363     /**
   219      * Disposes this instance
   364      * Disposes this instance
   220      */
   365      */
   221     void dispose()
   366     void dispose()
   222     {
   367     {
   223         doRelease();
   368     	if(gc != null) 
   224         gc.dispose();
   369     	{
   225         gc = null;
   370             doRelease();
       
   371             gc.dispose();
       
   372             gc = null;
       
   373     	}
   226         commandBuffer = null;
   374         commandBuffer = null;
   227     }
   375     }
   228 
   376 
   229     void copyArea(int x1, int y1, int width, int height, int x2, int y2, Graphics client)
   377     void copyArea(int x1, int y1, int width, int height, int x2, int y2, Graphics client)
   230     {
   378     {
   499         return new Rectangle(xInDpy, yInDpy, xInDpy + w, yInDpy + h);
   647         return new Rectangle(xInDpy, yInDpy, xInDpy + w, yInDpy + h);
   500     }
   648     }
   501 
   649 
   502 
   650 
   503     /**
   651     /**
       
   652      * Returns the WindowSurface that relates to this Buffer
       
   653      *
       
   654      * @return WindowSurface owned by this Buffer
       
   655      */
       
   656     WindowSurface getWindowSurface()
       
   657     {
       
   658         return null;
       
   659     }
       
   660     
       
   661     /**
   504      * Translates given rectangle to display/window surface coordinates
   662      * Translates given rectangle to display/window surface coordinates
   505      * and outlines the clip inside the control bounds.
   663      * and outlines the clip inside the control bounds.
   506      *
   664      *
   507      * @param x The x-coordinate of the rectangle
   665      * @param x The x-coordinate of the rectangle
   508      * @param y The y-coordinate of the rectangle
   666      * @param y The y-coordinate of the rectangle
   605                 bufferFontHandle = fontHandle;
   763                 bufferFontHandle = fontHandle;
   606             }
   764             }
   607         }
   765         }
   608         if((STROKESTYLE & flags) != 0)
   766         if((STROKESTYLE & flags) != 0)
   609         {
   767         {
   610             if(bufferStrokeStyle != client.currentStrokeSyle)
   768             if(bufferStrokeStyle != client.currentStrokeStyle)
   611             {
   769             {
   612                 gc.setStrokeStyle(Graphics.mapStrokeStyle(client.currentStrokeSyle));
   770                 gc.setStrokeStyle(Graphics.mapStrokeStyle(client.currentStrokeStyle));
   613                 bufferStrokeStyle = client.currentStrokeSyle;
   771                 bufferStrokeStyle = client.currentStrokeStyle;
   614             }
   772             }
   615         }
   773         }
   616     }
   774     }
   617 
   775 
   618     private boolean clientChanged(Graphics client)
   776     private boolean clientChanged(Graphics client)
   653                 gc.translate(bufferTranslateX, bufferTranslateY);
   811                 gc.translate(bufferTranslateX, bufferTranslateY);
   654             }
   812             }
   655         }
   813         }
   656     }
   814     }
   657 
   815 
       
   816    /**
       
   817     * Writes Graphics default values to buffer
       
   818     */
       
   819     private void writeDefaultValuesToBuffer()
       
   820     {
       
   821         int handle = Font.getESWTFont(defaultFont).handle;
       
   822         gc.setFont(handle);
       
   823         bufferFontHandle = handle;
       
   824         gc.setBackgroundColor(defaultColor, true);
       
   825         gc.setForegroundColor(defaultColor, true);
       
   826         bufferColor = defaultColor;
       
   827         gc.setStrokeStyle(Graphics.mapStrokeStyle(defaultStrokeStyle));
       
   828         bufferStrokeStyle = defaultStrokeStyle;
       
   829         gc.resetTransform();
       
   830         bufferTranslateX = defaultTranslateX;
       
   831         bufferTranslateY = defaultTranslateY;
       
   832     }
       
   833     
   658     private void doRelease()
   834     private void doRelease()
   659     {
   835     {
   660         gc.releaseTarget();
   836         gc.releaseTarget();
   661     }
   837     }
   662 }
   838 }