[Libreoffice-commits] core.git: 28 commits - android/Bootstrap android/experimental configure.ac desktop/source include/LibreOfficeKit include/vcl libreofficekit/source README.Android sal/osl solenv/bin sw/inc sw/source

Tomaž Vajngerl tomaz.vajngerl at collabora.co.uk
Mon Feb 16 00:21:31 PST 2015


 README.Android                                                                        |   30 -
 android/Bootstrap/src/org/libreoffice/kit/Document.java                               |   18 
 android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_img.png                  |binary
 android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_split_img.png            |binary
 android/experimental/LOAndroid3/res/drawable-hdpi/light_view_as_grid.png              |binary
 android/experimental/LOAndroid3/res/drawable-hdpi/lo_icon.png                         |binary
 android/experimental/LOAndroid3/res/drawable-ldpi/lo_icon.png                         |binary
 android/experimental/LOAndroid3/res/drawable-mdpi/background.png                      |binary
 android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_img.png                  |binary
 android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_split_img.png            |binary
 android/experimental/LOAndroid3/res/drawable-mdpi/lo_icon.png                         |binary
 android/experimental/LOAndroid3/res/drawable-mdpi/shadow.png                          |binary
 android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_img.png                 |binary
 android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_split_img.png           |binary
 android/experimental/LOAndroid3/res/drawable/calc.png                                 |binary
 android/experimental/LOAndroid3/res/drawable/dummy_page.png                           |binary
 android/experimental/LOAndroid3/res/drawable/folder.png                               |binary
 android/experimental/LOAndroid3/res/drawable/writer.png                               |binary
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOAbout.java                 |   21 
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java                 |   26 -
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOEventFactory.java          |    7 
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java             |   43 +
 android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java       |    4 
 android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java |    7 
 android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorLayer.java         |    1 
 android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java          |    4 
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java |    7 
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java  |   11 
 android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java           |  236 +++++++++-
 configure.ac                                                                          |    2 
 desktop/source/lib/init.cxx                                                           |   18 
 desktop/source/lib/lokandroid.cxx                                                     |    7 
 dev/null                                                                              |binary
 include/LibreOfficeKit/LibreOfficeKit.h                                               |   36 +
 include/LibreOfficeKit/LibreOfficeKit.hxx                                             |   12 
 include/LibreOfficeKit/LibreOfficeKitGtk.h                                            |   26 +
 include/vcl/ITiledRenderable.hxx                                                      |    7 
 libreofficekit/source/gtk/lokdocview.c                                                |  208 ++++++++
 sal/osl/unx/file.cxx                                                                  |    3 
 solenv/bin/native-code.py                                                             |    8 
 sw/inc/unotxdoc.hxx                                                                   |    2 
 sw/inc/viscrs.hxx                                                                     |    2 
 sw/source/core/crsr/viscrs.cxx                                                        |   79 +--
 sw/source/uibase/docvw/edtwin.cxx                                                     |   16 
 sw/source/uibase/inc/edtwin.hxx                                                       |    2 
 sw/source/uibase/uno/unotxdoc.cxx                                                     |   22 
 46 files changed, 713 insertions(+), 152 deletions(-)

New commits:
commit 0ccf2c77e55c11393baca166369e3ffe5d2863c2
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Feb 13 20:35:40 2015 +0900

    android: discard image buffer as soon as we upload to a texture
    
    Before TileLayer (which SubTile was a subclass of) held the
    image buffer for the whole life cycle of the tile, which wastes
    memory in case of SubTile as the image doesn't change (or changes
    only when invalidated) for the whole tile lifecycle. This change
    changes the SubTile inheritance to a general Layer and adds modified
    logic from SingleTileLayer and TileLayer. In addition it now
    discards the buffer as soon as it has been uploaded to a texture
    so that it doesn't takes up double the memory anymore.
    
    Change-Id: Ia104687d2df529182af412102459952b53e87950

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index c28806c..44cb7e3 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -7,6 +7,7 @@ import android.util.Log;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
+import org.mozilla.gecko.gfx.BufferedCairoImage;
 import org.mozilla.gecko.gfx.CairoImage;
 import org.mozilla.gecko.gfx.ComposedTileLayer;
 import org.mozilla.gecko.gfx.GeckoLayerClient;
@@ -38,7 +39,8 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
             CairoImage image = mTileProvider.createTile(tileId.x, tileId.y, tileId.size, tileId.zoom);
             if (image != null) {
                 mLayerClient.beginDrawing();
-                SubTile tile = new SubTile(image, tileId);
+                SubTile tile = new SubTile(tileId);
+                tile.setImage(image);
                 composedTileLayer.addTile(tile);
                 mLayerClient.endDrawing();
                 mLayerClient.forceRender();
@@ -57,7 +59,8 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         mLayerClient.invalidateTiles(tiles, rect);
 
         for (SubTile tile : tiles) {
-            mTileProvider.rerenderTile(tile.getImage(), tile.id.x, tile.id.y, tile.id.size, tile.id.zoom);
+            CairoImage image = mTileProvider.createTile(tile.id.x, tile.id.y, tile.id.size, tile.id.zoom);
+            tile.setImage(image);
         }
 
         mLayerClient.beginDrawing();
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java
index b5af410..342dc3c 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java
@@ -6,16 +6,64 @@
 package org.mozilla.gecko.gfx;
 
 import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.graphics.RegionIterator;
+import android.opengl.GLES20;
+import android.util.Log;
 
 import org.libreoffice.TileIdentifier;
 
-public class SubTile extends SingleTileLayer {
-    public boolean markedForRemoval = false;
+import java.nio.ByteBuffer;
+import java.nio.FloatBuffer;
+
+public class SubTile extends Layer {
+    private static String LOGTAG = SubTile.class.getSimpleName();
     public final TileIdentifier id;
 
-    public SubTile(CairoImage mImage, TileIdentifier id) {
-        super(mImage);
+    private final RectF mBounds;
+    private final RectF mTextureBounds;
+    private final RectF mViewport;
+    private final Rect mIntBounds;
+    private final Rect mSubRect;
+    private final RectF mSubRectF;
+    private final Region mMaskedBounds;
+    private final Rect mCropRect;
+    private final RectF mObjRectF;
+    private final float[] mCoords;
+
+    public boolean markedForRemoval = false;
+
+    private CairoImage mImage;
+    private IntSize mSize;
+    private int[] mTextureIDs;
+    private boolean mDirtyTile;
+
+    public SubTile(TileIdentifier id) {
+        super();
         this.id = id;
+
+        mBounds = new RectF();
+        mTextureBounds = new RectF();
+        mViewport = new RectF();
+        mIntBounds = new Rect();
+        mSubRect = new Rect();
+        mSubRectF = new RectF();
+        mMaskedBounds = new Region();
+        mCropRect = new Rect();
+        mObjRectF = new RectF();
+        mCoords = new float[20];
+
+        mImage = null;
+        mTextureIDs = null;
+        mSize = new IntSize(0, 0);
+        mDirtyTile = false;
+    }
+
+    public void setImage(CairoImage image) {
+        if (image.getSize().isPositive()) {
+            this.mImage = image;
+        }
     }
 
     public void refreshTileMetrics() {
@@ -25,4 +73,184 @@ public class SubTile extends SingleTileLayer {
     public void markForRemoval() {
         markedForRemoval = true;
     }
+
+    protected int getTextureID() {
+        return mTextureIDs[0];
+    }
+
+    protected boolean initialized() {
+        return mTextureIDs != null;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroyImage();
+            cleanTexture(false);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private void cleanTexture(boolean immediately) {
+        if (mTextureIDs != null) {
+            TextureReaper.get().add(mTextureIDs);
+            mTextureIDs = null;
+            if (immediately) {
+                TextureReaper.get().reap();
+            }
+        }
+    }
+
+    public void destroy() {
+        try {
+            destroyImage();
+            cleanTexture(false);
+        } catch (Exception ex) {
+            Log.e(LOGTAG, "Error clearing buffers: ", ex);
+        }
+    }
+
+    public void destroyImage() {
+        if (mImage != null) {
+            mImage.destroy();
+            mImage = null;
+        }
+    }
+
+    /**
+     * Invalidates the entire buffer so that it will be uploaded again. Only valid inside a
+     * transaction.
+     */
+    public void invalidate() {
+        if (!inTransaction()) {
+            throw new RuntimeException("invalidate() is only valid inside a transaction");
+        }
+        if (mImage == null) {
+            return;
+        }
+        mDirtyTile = true;
+    }
+
+    /**
+     * Remove the texture if the image is of different size than the current uploaded texture.
+     */
+    private void validateTexture() {
+        IntSize textureSize = mImage.getSize().nextPowerOfTwo();
+
+        if (!textureSize.equals(mSize)) {
+            mSize = textureSize;
+            cleanTexture(true);
+        }
+    }
+
+    @Override
+    protected void performUpdates(RenderContext context) {
+        super.performUpdates(context);
+        if (mImage == null && !mDirtyTile) {
+            return;
+        }
+        validateTexture();
+        uploadNewTexture();
+        mDirtyTile = false;
+    }
+
+    private void uploadNewTexture() {
+        ByteBuffer imageBuffer = mImage.getBuffer();
+        if (imageBuffer == null) {
+            return;
+        }
+
+        if (mTextureIDs == null) {
+            mTextureIDs = new int[1];
+            GLES20.glGenTextures(mTextureIDs.length, mTextureIDs, 0);
+        }
+
+        int cairoFormat = mImage.getFormat();
+        CairoGLInfo glInfo = new CairoGLInfo(cairoFormat);
+
+        bindAndSetGLParameters();
+
+        IntSize bufferSize = mImage.getSize();
+
+        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, glInfo.internalFormat,
+                mSize.width, mSize.height, 0, glInfo.format, glInfo.type, imageBuffer);
+
+        destroyImage();
+    }
+
+    private void bindAndSetGLParameters() {
+        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]);
+
+        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
+        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
+        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
+        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
+    }
+
+    @Override
+    public void draw(RenderContext context) {
+        // mTextureIDs may be null here during startup if Layer.java's draw method
+        // failed to acquire the transaction lock and call performUpdates.
+        if (!initialized())
+            return;
+
+        mViewport.set(context.viewport);
+
+        mBounds.set(getBounds(context));
+        mTextureBounds.set(mBounds);
+
+        mBounds.roundOut(mIntBounds);
+        mMaskedBounds.set(mIntBounds);
+
+        // XXX Possible optimisation here, form this array so we can draw it in
+        //     a single call.
+        RegionIterator iterator = new RegionIterator(mMaskedBounds);
+        while (iterator.next(mSubRect)) {
+            // Compensate for rounding errors at the edge of the tile caused by
+            // the roundOut above
+            mSubRectF.set(Math.max(mBounds.left, (float) mSubRect.left),
+                    Math.max(mBounds.top, (float) mSubRect.top),
+                    Math.min(mBounds.right, (float) mSubRect.right),
+                    Math.min(mBounds.bottom, (float) mSubRect.bottom));
+
+            // This is the left/top/right/bottom of the rect, relative to the
+            // bottom-left of the layer, to use for texture coordinates.
+            mCropRect.set(Math.round(mSubRectF.left - mBounds.left),
+                    Math.round(mBounds.bottom - mSubRectF.top),
+                    Math.round(mSubRectF.right - mBounds.left),
+                    Math.round(mBounds.bottom - mSubRectF.bottom));
+
+            mObjRectF.set(mSubRectF.left - mViewport.left,
+                    mViewport.bottom - mSubRectF.bottom,
+                    mSubRectF.right - mViewport.left,
+                    mViewport.bottom - mSubRectF.top);
+
+            fillRectCoordBuffer(mCoords, mObjRectF, mViewport.width(), mViewport.height(), mCropRect, mTextureBounds.width(), mTextureBounds.height());
+
+            FloatBuffer coordBuffer = context.coordBuffer;
+            int positionHandle = context.positionHandle;
+            int textureHandle = context.textureHandle;
+
+            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID());
+
+            // Make sure we are at position zero in the buffer
+            coordBuffer.position(0);
+            coordBuffer.put(mCoords);
+
+            // Unbind any the current array buffer so we can use client side buffers
+            GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+
+            // Vertex coordinates are x,y,z starting at position 0 into the buffer.
+            coordBuffer.position(0);
+            GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer);
+
+            // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer.
+            coordBuffer.position(3);
+            GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer);
+            GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+        }
+    }
 }
commit 0e98675b693c925c54a3820596dbad130ad73b35
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Feb 13 18:29:52 2015 +0900

    android: remove tileRerender method as it is obsolete
    
    Change-Id: I0087edfd2c93a80417b0002eac96e7626c35baf2

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index cef7ac8..c28806c 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -48,20 +48,6 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         }
     }
 
-    private void tileRerender(ComposedTileLayer composedTileLayer, SubTile tile) {
-        if (mTileProvider == null) {
-            return;
-        }
-
-        if (composedTileLayer.isStillValid(tile.id) && !tile.markedForRemoval) {
-            mLayerClient.beginDrawing();
-            mTileProvider.rerenderTile(tile.getImage(), tile.id.x, tile.id.y, tile.id.size, tile.id.zoom);
-            tile.invalidate();
-            mLayerClient.endDrawing();
-            mLayerClient.forceRender();
-        }
-    }
-
     private void tileInvalidation(RectF rect) {
         if (mLayerClient == null || mTileProvider == null) {
             return;
commit 71c568406613c3aa423679dcc5f63b6b24d11f03
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Feb 13 18:24:55 2015 +0900

    android: remove ImmutableViewportMetrics as input to endDrawing
    
    Change-Id: Iec55bc182845bfa09cf6d03ab787fc1f2e0ee7fc

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index a737d18..cef7ac8 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -40,7 +40,7 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
                 mLayerClient.beginDrawing();
                 SubTile tile = new SubTile(image, tileId);
                 composedTileLayer.addTile(tile);
-                mLayerClient.endDrawing(mViewportMetrics);
+                mLayerClient.endDrawing();
                 mLayerClient.forceRender();
             }
         } else {
@@ -57,7 +57,7 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
             mLayerClient.beginDrawing();
             mTileProvider.rerenderTile(tile.getImage(), tile.id.x, tile.id.y, tile.id.size, tile.id.zoom);
             tile.invalidate();
-            mLayerClient.endDrawing(mViewportMetrics);
+            mLayerClient.endDrawing();
             mLayerClient.forceRender();
         }
     }
@@ -78,7 +78,7 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         for (SubTile tile : tiles) {
             tile.invalidate();
         }
-        mLayerClient.endDrawing(mViewportMetrics);
+        mLayerClient.endDrawing();
         mLayerClient.forceRender();
     }
 
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index 83a1324..93beb3d 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -240,7 +240,7 @@ public class GeckoLayerClient implements PanZoomTarget, LayerView.Listener {
         mRootLayer.beginTransaction();
     }
 
-    public void endDrawing(ImmutableViewportMetrics viewportMetrics) {
+    public void endDrawing() {
         synchronized (this) {
             mLowResLayer.endTransaction();
             mRootLayer.endTransaction();
commit 05b49687acb1661448c99c90f40854feeda8bda3
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Feb 13 18:23:53 2015 +0900

    android: organise imports
    
    Change-Id: I0f71bade1172b143f0f261ab6ed741f5dd3a9d93

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOAbout.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOAbout.java
index 13c436f..b34b2c4 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOAbout.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOAbout.java
@@ -2,27 +2,14 @@ package org.libreoffice;
 
 import android.app.Activity;
 import android.app.AlertDialog;
-import android.content.DialogInterface;
 import android.content.ComponentName;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.v4.widget.DrawerLayout;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ListView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
+import android.content.DialogInterface;
 import android.content.Intent;
-import android.net.Uri;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.view.View;
+import android.widget.TextView;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.io.File;
 
 public abstract class LOAbout extends Activity {
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 17fa867..ad4d920 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -1,6 +1,5 @@
 package org.libreoffice;
 
-import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -8,10 +7,7 @@ import android.content.DialogInterface;
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.v4.widget.DrawerLayout;
-import android.util.DisplayMetrics;
 import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
@@ -19,10 +15,8 @@ import android.view.inputmethod.InputMethodManager;
 import android.widget.AdapterView;
 import android.widget.ListView;
 import android.widget.RelativeLayout;
-import android.widget.TextView;
 
 import org.mozilla.gecko.TextSelection;
-import org.mozilla.gecko.TextSelectionHandle;
 import org.mozilla.gecko.ZoomConstraints;
 import org.mozilla.gecko.gfx.GeckoLayerClient;
 import org.mozilla.gecko.gfx.LayerView;
@@ -30,7 +24,6 @@ import org.mozilla.gecko.gfx.LayerView;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorLayer.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorLayer.java
index e83a56c..1e6f167 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorLayer.java
@@ -5,7 +5,6 @@ import android.graphics.RectF;
 import android.util.Log;
 import android.view.View;
 
-import org.mozilla.gecko.TextSelectionHandle;
 import org.mozilla.gecko.gfx.Layer;
 import org.mozilla.gecko.gfx.LayerView;
 import org.mozilla.gecko.util.FloatUtils;
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java
index 1aed2f0..b2508b6 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TextCursorView.java
@@ -1,13 +1,9 @@
 package org.libreoffice;
 
 import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PointF;
 import android.graphics.RectF;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.view.View;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 
commit c2b8fa6d9e69682344c66c62d30dfacf9ad51f82
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Fri Feb 13 18:16:51 2015 +0900

    android: invalidate all intersecting tiles in one LOEvent
    
    Change-Id: Ic21984016d10a8e3da87b9fb032179cd4f6f7b9f

diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
index a9600ea..c51b445 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEvent.java
@@ -1,12 +1,12 @@
 package org.libreoffice;
 
 import android.graphics.PointF;
+import android.graphics.RectF;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 import org.mozilla.gecko.gfx.ComposedTileLayer;
 import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.SubTile;
 
 public class LOEvent implements Comparable<LOEvent> {
     public static final int SIZE_CHANGED = 1;
@@ -17,7 +17,7 @@ public class LOEvent implements Comparable<LOEvent> {
     public static final int REDRAW = 6;
     public static final int TILE_REQUEST = 7;
     public static final int THUMBNAIL = 8;
-    public static final int TILE_RERENDER = 9;
+    public static final int TILE_INVALIDATION = 9;
     public static final int TOUCH = 10;
     public static final int KEY_EVENT = 11;
 
@@ -30,13 +30,12 @@ public class LOEvent implements Comparable<LOEvent> {
     public String mFilename;
     public TileIdentifier mTileId;
     public ComposedTileLayer mComposedTileLayer;
-    public boolean mForceRedraw;
-    public SubTile mTile;
     public String mTouchType;
     public MotionEvent mMotionEvent;
     public PointF mDocumentTouchCoordinate;
     public String mKeyEventType;
     public KeyEvent mKeyEvent;
+    public RectF mInvalidationRect;
 
     public LOEvent(int type) {
         mType = type;
@@ -47,12 +46,11 @@ public class LOEvent implements Comparable<LOEvent> {
         mTypeString = "Size Changed: " + widthPixels + " " + heightPixels;
     }
 
-    public LOEvent(int type, ComposedTileLayer composedTileLayer, TileIdentifier tileId, boolean forceRedraw) {
+    public LOEvent(int type, ComposedTileLayer composedTileLayer, TileIdentifier tileId) {
         mType = type;
         mTypeString = "Tile Request";
         mComposedTileLayer = composedTileLayer;
         mTileId = tileId;
-        mForceRedraw = forceRedraw;
     }
 
     public LOEvent(int type, String filename) {
@@ -75,13 +73,7 @@ public class LOEvent implements Comparable<LOEvent> {
     public LOEvent(int type, ThumbnailCreator.ThumbnailCreationTask task) {
         mType = type;
         mTask = task;
-    }
-
-    public LOEvent(int type, ComposedTileLayer composedTileLayer, SubTile tile) {
-        mType = type;
-        mTypeString = "Tile Rerender";
-        mComposedTileLayer = composedTileLayer;
-        mTile = tile;
+        mTypeString = "Thumbnail";
     }
 
     public LOEvent(int type, String touchType, MotionEvent motionEvent, PointF documentTouchCoordinate) {
@@ -94,11 +86,17 @@ public class LOEvent implements Comparable<LOEvent> {
 
     public LOEvent(int type, String keyEventType, KeyEvent keyEvent) {
         mType = type;
-        mTypeString = "KeyEvent";
+        mTypeString = "Key Event";
         mKeyEventType = keyEventType;
         mKeyEvent = keyEvent;
     }
 
+    public LOEvent(int type, RectF rect) {
+        mType = type;
+        mTypeString = "Tile Invalidation";
+        mInvalidationRect = rect;
+    }
+
     public String getTypeString() {
         if (mTypeString == null) {
             return "Event type: " + mType;
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEventFactory.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEventFactory.java
index b866850..71bceb2 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEventFactory.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOEventFactory.java
@@ -2,7 +2,6 @@ package org.libreoffice;
 
 import org.mozilla.gecko.gfx.ComposedTileLayer;
 import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.SubTile;
 
 
 public class LOEventFactory {
@@ -31,14 +30,10 @@ public class LOEventFactory {
     }
 
     public static LOEvent tileRequest(ComposedTileLayer composedTileLayer, TileIdentifier tileID, boolean forceRedraw) {
-        return new LOEvent(LOEvent.TILE_REQUEST, composedTileLayer, tileID, forceRedraw);
+        return new LOEvent(LOEvent.TILE_REQUEST, composedTileLayer, tileID);
     }
 
     public static LOEvent thumbnail(ThumbnailCreator.ThumbnailCreationTask task) {
         return new LOEvent(LOEvent.THUMBNAIL, task);
     }
-
-    public static LOEvent tileRerender(ComposedTileLayer composedTileLayer, SubTile tile) {
-        return new LOEvent(LOEvent.TILE_RERENDER, composedTileLayer, tile);
-    }
 }
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 3536256..a737d18 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -13,6 +13,8 @@ import org.mozilla.gecko.gfx.GeckoLayerClient;
 import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
 import org.mozilla.gecko.gfx.SubTile;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.PriorityBlockingQueue;
 
 public class LOKitThread extends Thread implements TileProvider.TileInvalidationCallback {
@@ -28,7 +30,7 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         TileProviderFactory.initialize();
     }
 
-    private void tileRequest(ComposedTileLayer composedTileLayer, TileIdentifier tileId, boolean forceRedraw) {
+    private void tileRequest(ComposedTileLayer composedTileLayer, TileIdentifier tileId) {
         if (mTileProvider == null)
             return;
 
@@ -47,8 +49,9 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
     }
 
     private void tileRerender(ComposedTileLayer composedTileLayer, SubTile tile) {
-        if (mTileProvider == null)
+        if (mTileProvider == null) {
             return;
+        }
 
         if (composedTileLayer.isStillValid(tile.id) && !tile.markedForRemoval) {
             mLayerClient.beginDrawing();
@@ -59,6 +62,26 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
         }
     }
 
+    private void tileInvalidation(RectF rect) {
+        if (mLayerClient == null || mTileProvider == null) {
+            return;
+        }
+
+        List<SubTile> tiles = new ArrayList<SubTile>();
+        mLayerClient.invalidateTiles(tiles, rect);
+
+        for (SubTile tile : tiles) {
+            mTileProvider.rerenderTile(tile.getImage(), tile.id.x, tile.id.y, tile.id.size, tile.id.zoom);
+        }
+
+        mLayerClient.beginDrawing();
+        for (SubTile tile : tiles) {
+            tile.invalidate();
+        }
+        mLayerClient.endDrawing(mViewportMetrics);
+        mLayerClient.forceRender();
+    }
+
     /** Handle the geometry change + draw. */
     private void redraw() {
         if (mLayerClient == null || mTileProvider == null) {
@@ -159,10 +182,10 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
                 changePart(event.mPartIndex);
                 break;
             case LOEvent.TILE_REQUEST:
-                tileRequest(event.mComposedTileLayer, event.mTileId, event.mForceRedraw);
+                tileRequest(event.mComposedTileLayer, event.mTileId);
                 break;
-            case LOEvent.TILE_RERENDER:
-                tileRerender(event.mComposedTileLayer, event.mTile);
+            case LOEvent.TILE_INVALIDATION:
+                tileInvalidation(event.mInvalidationRect);
                 break;
             case LOEvent.THUMBNAIL:
                 createThumbnail(event.mTask);
@@ -216,10 +239,7 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
 
     @Override
     public void invalidate(RectF rect) {
-        Log.i(LOGTAG, "Invalidate request: " + rect);
-
-        mLayerClient = mApplication.getLayerClient();
-        mLayerClient.invalidateTiles(rect);
+        queueEvent(new LOEvent(LOEvent.TILE_INVALIDATION, rect));
     }
 }
 
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
index ca25438..02fa4fa 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
@@ -1,6 +1,5 @@
 package org.mozilla.gecko.gfx;
 
-import android.app.ActivityManager;
 import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -212,12 +211,12 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
     /**
      * Invalidate tiles which intersect the input rect
      */
-    public void invalidateTiles(RectF cssRect) {
+    public void invalidateTiles(List<SubTile> tilesToInvalidate, RectF cssRect) {
         RectF zoomedRect = RectUtils.scale(cssRect, currentZoom);
 
         for (SubTile tile : tiles) {
-            if (RectF.intersects(zoomedRect, tile.id.getRectF())) {
-                LOKitShell.sendEvent(LOEventFactory.tileRerender(this, tile));
+            if (!tile.markedForRemoval && RectF.intersects(zoomedRect, tile.id.getRectF())) {
+                tilesToInvalidate.add(tile);
             }
         }
     }
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index 644ef46..83a1324 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -15,9 +15,12 @@ import android.util.Log;
 import org.libreoffice.LOEvent;
 import org.libreoffice.LOEventFactory;
 import org.libreoffice.LOKitShell;
+import org.libreoffice.LOKitThread;
 import org.mozilla.gecko.ZoomConstraints;
 import org.mozilla.gecko.util.FloatUtils;
 
+import java.util.List;
+
 public class GeckoLayerClient implements PanZoomTarget, LayerView.Listener {
     private static final String LOGTAG = GeckoLayerClient.class.getSimpleName();
 
@@ -388,8 +391,8 @@ public class GeckoLayerClient implements PanZoomTarget, LayerView.Listener {
         mRootLayer.clearAndReset();
     }
 
-    public void invalidateTiles(RectF rect) {
-        mLowResLayer.invalidateTiles(rect);
-        mRootLayer.invalidateTiles(rect);
+    public void invalidateTiles(List<SubTile> tilesToInvalidate, RectF rect) {
+        mLowResLayer.invalidateTiles(tilesToInvalidate, rect);
+        mRootLayer.invalidateTiles(tilesToInvalidate, rect);
     }
 }
\ No newline at end of file
commit 1eb2de90bee8a0585655573eaebcc901495edd4d
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Feb 12 17:14:13 2015 +0900

    android: add support for text selection to JNI
    
    Change-Id: Ifa307eb6a8cb031bdd88b9fadae42c8a0811772b

diff --git a/android/Bootstrap/src/org/libreoffice/kit/Document.java b/android/Bootstrap/src/org/libreoffice/kit/Document.java
index cb798b5..ca2f38c 100644
--- a/android/Bootstrap/src/org/libreoffice/kit/Document.java
+++ b/android/Bootstrap/src/org/libreoffice/kit/Document.java
@@ -38,6 +38,16 @@ public class Document {
      */
     public static final int CALLBACK_INVALIDATE_TILES = 0;
     public static final int CALLBACK_INVALIDATE_VISIBLE_CURSOR = 1;
+    public static final int CALLBACK_INVALIDATE_TEXT_SELECTION = 2;
+    public static final int CALLBACK_INVALIDATE_TEXT_SELECTION_START = 3;
+    public static final int CALLBACK_INVALIDATE_TEXT_SELECTION_END = 4;
+
+    /**
+     * Text selection types
+     */
+    public static final int TEXT_SELECTION_START = 0;
+    public static final int TEXT_SELECTION_END = 1;
+    public static final int TEXT_SELECTION_RESET = 2;
 
     private final ByteBuffer handle;
     private MessageCallback messageCallback = null;
@@ -108,6 +118,14 @@ public class Document {
     public native void postMouseEvent(int type, int x, int y, int count);
 
     /**
+     * Change text selection
+     * @param type - text selection type
+     * @param x - x coordinate
+     * @param y - y coordinate
+     */
+    public native void setTextSelection(int type, int x, int y);
+
+    /**
      * Callback to retrieve messages from LOK
      */
     public interface MessageCallback {
diff --git a/desktop/source/lib/lokandroid.cxx b/desktop/source/lib/lokandroid.cxx
index d253cfe..5403ea0 100644
--- a/desktop/source/lib/lokandroid.cxx
+++ b/desktop/source/lib/lokandroid.cxx
@@ -284,6 +284,13 @@ extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Document_postMou
     pDocument->pClass->postMouseEvent(pDocument, type, x, y, count);
 }
 
+extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Document_setTextSelection
+    (JNIEnv* pEnv, jobject aObject, jint type, jint x, jint y)
+{
+    LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);
+    pDocument->pClass->setTextSelection(pDocument, type, x, y);
+}
+
 /* DirectBufferAllocator */
 
 extern "C" SAL_JNI_EXPORT jobject JNICALL Java_org_libreoffice_kit_DirectBufferAllocator_allocateDirectBufferNative
commit 63ae4c065122f5d44a0dfe8fcfa0cddcb14bca66
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date:   Thu Feb 12 16:31:50 2015 +0900

    Enable mpCursorOverlay for Android too
    
    Commit 8fc976698e4d3d04f61cbad96c0c977ef15115d6 enables a code
    path that needs mpCursorOverlay, which was not enabled for Android
    and caused the build to fail.
    
    Change-Id: I88fe0be23c25c6b14170b2a3505aa2be01f73e0b

diff --git a/sw/inc/viscrs.hxx b/sw/inc/viscrs.hxx
index 1d364e0..b24bea5 100644
--- a/sw/inc/viscrs.hxx
+++ b/sw/inc/viscrs.hxx
@@ -71,7 +71,7 @@ class SwSelPaintRects : public SwRects
 
     const SwCrsrShell* pCShell;
 
-#if HAVE_FEATURE_DESKTOP
+#if HAVE_FEATURE_DESKTOP || defined(ANDROID)
     sdr::overlay::OverlayObject*    mpCursorOverlay;
 
     // access to mpCursorOverlay for swapContent
commit 1e4d83a578933a1acd4d7d0c68b56f37987170cb
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Wed Feb 11 10:33:40 2015 +0100

    native-code.py: Add com_sun_star_comp_dba_ORowSet_get_implementation.
    
    In the end, seems to be enough (together with a checkbox-related constructor)
    to make the fields.doc work.
    
    Change-Id: I72bf2020726aabed9b7d8cf45c23c131361f9907

diff --git a/solenv/bin/native-code.py b/solenv/bin/native-code.py
index b438b1e..0d4bdc0 100755
--- a/solenv/bin/native-code.py
+++ b/solenv/bin/native-code.py
@@ -85,6 +85,8 @@ core_constructor_list = [
     "com_sun_star_comp_chart2_XMLFilter_get_implementation",
 # chart2/source/controller/chartcontroller.component
     "com_sun_star_comp_chart2_ChartDocumentWrapper_get_implementation",
+# dbaccess/util/dba.component
+    "com_sun_star_comp_dba_ORowSet_get_implementation",
 # forms/util/frm.component
     "com_sun_star_comp_forms_ODatabaseForm_get_implementation",
     "com_sun_star_form_OFormsCollection_get_implementation",
@@ -143,6 +145,7 @@ core_constructor_list = [
 # stoc/source/inspect/introspection.component
     "com_sun_star_comp_stoc_Introspection_get_implementation",
 # toolkit/util/tk.component
+    "stardiv_Toolkit_UnoCheckBoxControl_get_implementation",
     "stardiv_Toolkit_UnoComboBoxControl_get_implementation",
     "stardiv_Toolkit_UnoControlCheckBoxModel_get_implementation",
     "stardiv_Toolkit_UnoControlComboBoxModel_get_implementation",
commit 006c0a3122b173bd953856d6d2f3ce57e4eab5f7
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Feb 11 10:23:20 2015 +0100

    Enable LOK_CALLBACK_TEXT_SELECTION_START/END on Android
    
    Change-Id: Id00fcb6fb74652ed38d43b83338ddb0c549c5ae6

diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index 0b0d63c..46b740b 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -284,7 +284,7 @@ void SwSelPaintRects::Show()
         SwRects::clear();
         FillRects();
 
-#if HAVE_FEATURE_DESKTOP
+#if HAVE_FEATURE_DESKTOP || defined(ANDROID)
         // get new rects
         std::vector< basegfx::B2DRange > aNewRanges;
 
@@ -365,47 +365,6 @@ void SwSelPaintRects::Show()
         }
 
         HighlightInputFld();
-#else
-
-#if 0 // Totally unclear what we want to do here?
-
-        const OutputDevice* pOut = GetShell()->GetWin();
-        if ( ! pOut )
-            pOut = GetShell()->GetOut();
-        SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>(const_cast<SwCrsrShell*>(GetShell()));
-        if (!empty())
-        {
-            if (pWrtShell)
-            {
-
-                // Buffer will be deallocated in the UI layer
-                MLORect *rects = (MLORect *) malloc((sizeof(MLORect))*size());
-                for (size_t i = 0; i < size(); ++i)
-                {
-                    Point origin = pOut->LogicToPixel((*this)[i].Pos());
-                    Size ssize = pOut->LogicToPixel((*this)[i].SSize());
-#ifdef IOS
-                    rects[i] = CGRectMake(origin.X(), origin.Y(),
-                                          ssize.Width(), ssize.Height());
-#else
-                    // Not yet implemented
-                    (void) origin;
-                    (void) ssize;
-#endif
-                }
-                // GetShell returns a SwCrsrShell which actually is a SwWrtShell
-
-                // touch_ui_selection_start() was dummy both in TiledLibreOffice (iOS) and for Android
-                // touch_ui_selection_start(MLOSelectionText, pWrtShell, rects, size(), NULL);
-            }
-        }
-        else
-        {
-            // touch_ui_selection_none was dummy both in TiledLibreOffice (iOS) and for Android
-            // touch_ui_selection_none();
-        }
-#endif
-
 #endif
     }
 }
commit 2f38b80b486015c1ddb219cf006c1705d2c43872
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Feb 11 09:19:06 2015 +0100

    LOK: add LOK_SETTEXTSELECTION_RESET
    
    So clients can perform a single method call to adjust the cursor
    position (when it's not a range), instead of sending two mouse clicks.
    This is mostly to be consistent, so that adjusting the cursor's middle
    and start/end handles all result in a setTextSelection() LOK call.
    
    Change-Id: I09eb0811887d173ea9ad7d125a2afb2c9e5c918c

diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index eccf19b..9c5cca5 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -122,7 +122,9 @@ typedef enum
     /// The start of selection is to be adjusted.
     LOK_SETTEXTSELECTION_START,
     /// The end of selection is to be adjusted.
-    LOK_SETTEXTSELECTION_END
+    LOK_SETTEXTSELECTION_END,
+    /// Both the start and the end of selection is to be adjusted.
+    LOK_SETTEXTSELECTION_RESET
 }
 LibreOfficeKitSetTextSelectionType;
 
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 61d107c..132b2d4 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -74,8 +74,7 @@ gboolean lcl_signalMotion(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
     {
         g_info("lcl_signalMotion: dragging the middle handle");
         lcl_getDragPoint(&pDocView->m_aHandleMiddleRect, pEvent, &aPoint);
-        pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
-        pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
+        pDocView->pDocument->pClass->setTextSelection(pDocView->pDocument, LOK_SETTEXTSELECTION_RESET, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y));
     }
     else if (pDocView->m_bInDragStartHandle)
     {
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index bb59217..53a1abb 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -6256,11 +6256,13 @@ void SwEditWin::LogicMouseButtonUp(const MouseEvent& rMouseEvent)
     MouseButtonUp(rMouseEvent);
 }
 
-void SwEditWin::SetCursorLogicPosition(bool bPoint, const Point& rPosition)
+void SwEditWin::SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark)
 {
     // Not an SwWrtShell, as that would make SwCrsrShell::GetCrsr() inaccessible.
     SwEditShell& rShell = m_rView.GetWrtShell();
     SwMvContext aMvContext(&rShell);
+    if (bClearMark)
+        rShell.ClearMark();
     // If the mark is to be updated, then exchange the point and mark before
     // and after, as we can't easily set the mark.
     if (!bPoint)
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index 9af9446..4e8ff48 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -306,7 +306,7 @@ public:
     /// Same as MouseButtonUp(), but coordinates are in logic unit.
     void LogicMouseButtonUp(const MouseEvent& rMouseEvent);
     /// Allows adjusting the point or mark of the selection to a document coordinate.
-    void SetCursorLogicPosition(bool bPoint, const Point& rPosition);
+    void SetCursorLogicPosition(const Point& rPosition, bool bPoint, bool bClearMark);
 };
 
 #endif
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 3a98cd9..88320e8 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3202,10 +3202,13 @@ void SwXTextDocument::setTextSelection(int nType, int nX, int nY)
     switch (nType)
     {
     case LOK_SETTEXTSELECTION_START:
-        rEditWin.SetCursorLogicPosition(/*bPoint=*/false, Point(nX, nY));
+        rEditWin.SetCursorLogicPosition(Point(nX, nY), /*bPoint=*/false, /*bClearMark=*/false);
         break;
     case LOK_SETTEXTSELECTION_END:
-        rEditWin.SetCursorLogicPosition(/*bPoint=*/true, Point(nX, nY));
+        rEditWin.SetCursorLogicPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/false);
+        break;
+    case LOK_SETTEXTSELECTION_RESET:
+        rEditWin.SetCursorLogicPosition(Point(nX, nY), /*bPoint=*/true, /*bClearMark=*/true);
         break;
     default:
         assert(false);
commit f26dd84f6b99037c75364984bfca57369ae2095f
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 18:40:02 2015 +0100

    lokdocview: reset start/end or middle handle depending on if we have selection
    
    Change-Id: Iee5511a8077e37999865aa83da2dfde1fdd4dbc2

diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index a9644b7..61d107c 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -604,8 +604,12 @@ static gboolean lok_docview_callback(gpointer pData)
         if (pRectangles == NULL)
         {
             memset(&pDocView->m_aTextSelectionStart, 0, sizeof(pDocView->m_aTextSelectionStart));
+            memset(&pDocView->m_aHandleStartRect, 0, sizeof(pDocView->m_aHandleStartRect));
             memset(&pDocView->m_aTextSelectionEnd, 0, sizeof(pDocView->m_aTextSelectionEnd));
+            memset(&pDocView->m_aHandleEndRect, 0, sizeof(pDocView->m_aHandleEndRect));
         }
+        else
+            memset(&pDocView->m_aHandleMiddleRect, 0, sizeof(pDocView->m_aHandleMiddleRect));
         gtk_widget_queue_draw(GTK_WIDGET(pDocView->pEventBox));
     }
     break;
commit 5e5649afeb0e56b0c6852bfac42f53e0c5c958ee
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 18:35:00 2015 +0100

    lokdocview: allow dragging the selection start handle, too
    
    Change-Id: Ic5dd96c4ced7c5ea67d4417c73721535302f754b

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 40ce630..c1a1731 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -56,8 +56,15 @@ struct _LOKDocView
     GdkRectangle m_aTextSelectionStart;
     /// Position and size of the selection end.
     GdkRectangle m_aTextSelectionEnd;
+
+    /// @name Start/middle/end handle.
+    ///@{
     /// Bitmap of the text selection start handle.
     cairo_surface_t* m_pHandleStart;
+    /// Rectangle of the text selection start handle, to know if the user clicked on it or not
+    GdkRectangle m_aHandleStartRect;
+    /// If we are in the middle of a drag of the text selection end handle.
+    gboolean m_bInDragStartHandle;
     /// Bitmap of the text selection middle handle.
     cairo_surface_t* m_pHandleMiddle;
     /// Rectangle of the text selection middle handle, to know if the user clicked on it or not
@@ -70,6 +77,7 @@ struct _LOKDocView
     GdkRectangle m_aHandleEndRect;
     /// If we are in the middle of a drag of the text selection end handle.
     gboolean m_bInDragEndHandle;
+    ///@}
 };
 
 struct _LOKDocViewClass
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index c18ccc0..a9644b7 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -67,20 +67,24 @@ void lcl_getDragPoint(GdkRectangle* pHandle, GdkEventButton* pEvent, GdkPoint* p
 
 gboolean lcl_signalMotion(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView)
 {
+    GdkPoint aPoint;
+
     (void)pEventBox;
     if (pDocView->m_bInDragMiddleHandle)
     {
-        GdkPoint aPoint;
-
         g_info("lcl_signalMotion: dragging the middle handle");
         lcl_getDragPoint(&pDocView->m_aHandleMiddleRect, pEvent, &aPoint);
         pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
         pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
     }
+    else if (pDocView->m_bInDragStartHandle)
+    {
+        g_info("lcl_signalMotion: dragging the start handle");
+        lcl_getDragPoint(&pDocView->m_aHandleStartRect, pEvent, &aPoint);
+        pDocView->pDocument->pClass->setTextSelection(pDocView->pDocument, LOK_SETTEXTSELECTION_START, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y));
+    }
     else if (pDocView->m_bInDragEndHandle)
     {
-        GdkPoint aPoint;
-
         g_info("lcl_signalMotion: dragging the end handle");
         lcl_getDragPoint(&pDocView->m_aHandleEndRect, pEvent, &aPoint);
         pDocView->pDocument->pClass->setTextSelection(pDocView->pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y));
@@ -94,17 +98,26 @@ gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
     g_info("lcl_signalButton: %d, %d (in twips: %d, %d)", (int)pEvent->x, (int)pEvent->y, (int)pixelToTwip(pEvent->x), (int)pixelToTwip(pEvent->y));
     (void) pEventBox;
 
-    if (pDocView->m_bInDragMiddleHandle && pEvent->type == GDK_BUTTON_RELEASE)
-    {
-        g_info("lcl_signalButton: end of drag middle handle");
-        pDocView->m_bInDragMiddleHandle = FALSE;
-        return FALSE;
-    }
-    else if (pDocView->m_bInDragEndHandle && pEvent->type == GDK_BUTTON_RELEASE)
+    if (pEvent->type == GDK_BUTTON_RELEASE)
     {
-        g_info("lcl_signalButton: end of drag end handle");
-        pDocView->m_bInDragEndHandle = FALSE;
-        return FALSE;
+        if (pDocView->m_bInDragStartHandle)
+        {
+            g_info("lcl_signalButton: end of drag start handle");
+            pDocView->m_bInDragStartHandle = FALSE;
+            return FALSE;
+        }
+        else if (pDocView->m_bInDragMiddleHandle)
+        {
+            g_info("lcl_signalButton: end of drag middle handle");
+            pDocView->m_bInDragMiddleHandle = FALSE;
+            return FALSE;
+        }
+        else if (pDocView->m_bInDragEndHandle)
+        {
+            g_info("lcl_signalButton: end of drag end handle");
+            pDocView->m_bInDragEndHandle = FALSE;
+            return FALSE;
+        }
     }
 
     if (pDocView->m_bEdit)
@@ -114,17 +127,26 @@ gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
         aClick.y = pEvent->y;
         aClick.width = 1;
         aClick.height = 1;
-        if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleMiddleRect, NULL) && pEvent->type == GDK_BUTTON_PRESS)
-        {
-            g_info("lcl_signalButton: start of drag middle handle");
-            pDocView->m_bInDragMiddleHandle = TRUE;
-            return FALSE;
-        }
-        else if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleEndRect, NULL) && pEvent->type == GDK_BUTTON_PRESS)
+        if (pEvent->type == GDK_BUTTON_PRESS)
         {
-            g_info("lcl_signalButton: start of drag end handle");
-            pDocView->m_bInDragEndHandle = TRUE;
-            return FALSE;
+            if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleStartRect, NULL))
+            {
+                g_info("lcl_signalButton: start of drag start handle");
+                pDocView->m_bInDragStartHandle = TRUE;
+                return FALSE;
+            }
+            else if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleMiddleRect, NULL))
+            {
+                g_info("lcl_signalButton: start of drag middle handle");
+                pDocView->m_bInDragMiddleHandle = TRUE;
+                return FALSE;
+            }
+            else if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleEndRect, NULL))
+            {
+                g_info("lcl_signalButton: start of drag end handle");
+                pDocView->m_bInDragEndHandle = TRUE;
+                return FALSE;
+            }
         }
     }
 
@@ -219,11 +241,15 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_pTextSelectionRectangles = NULL;
     memset(&pDocView->m_aTextSelectionStart, 0, sizeof(pDocView->m_aTextSelectionStart));
     memset(&pDocView->m_aTextSelectionEnd, 0, sizeof(pDocView->m_aTextSelectionEnd));
+
+    // Start/middle/end handle.
     pDocView->m_pHandleStart = NULL;
+    memset(&pDocView->m_aHandleStartRect, 0, sizeof(pDocView->m_aHandleStartRect));
+    pDocView->m_bInDragStartHandle = FALSE;
     pDocView->m_pHandleMiddle = NULL;
-    pDocView->m_pHandleEnd = NULL;
     memset(&pDocView->m_aHandleMiddleRect, 0, sizeof(pDocView->m_aHandleMiddleRect));
     pDocView->m_bInDragMiddleHandle = FALSE;
+    pDocView->m_pHandleEnd = NULL;
     memset(&pDocView->m_aHandleEndRect, 0, sizeof(pDocView->m_aHandleEndRect));
     pDocView->m_bInDragEndHandle = FALSE;
 
@@ -360,7 +386,7 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
             // Have a start position: we need a start handle.
             if (!pDocView->m_pHandleStart)
                 pDocView->m_pHandleStart = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_start.png");
-            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionStart, pDocView->m_pHandleStart, NULL);
+            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionStart, pDocView->m_pHandleStart, &pDocView->m_aHandleStartRect);
         }
         if (!lcl_isEmptyRectangle(&pDocView->m_aTextSelectionEnd))
         {
commit be77714263eff4a6e60d192bd87dc5309a23fae0
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 18:19:32 2015 +0100

    lokdocview: allow dragging the selection end handle
    
    Change-Id: I977e93657c52a66f10762293835ead28451b5406

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 95288cd..40ce630 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -66,6 +66,10 @@ struct _LOKDocView
     gboolean m_bInDragMiddleHandle;
     /// Bitmap of the text selection end handle.
     cairo_surface_t* m_pHandleEnd;
+    /// Rectangle of the text selection end handle, to know if the user clicked on it or not
+    GdkRectangle m_aHandleEndRect;
+    /// If we are in the middle of a drag of the text selection end handle.
+    gboolean m_bInDragEndHandle;
 };
 
 struct _LOKDocViewClass
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 0fa3e11..c18ccc0 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -42,28 +42,49 @@ void lcl_onDestroy( LOKDocView* pDocView, gpointer pData )
     pDocView->pDocument = NULL;
 }
 
+/**
+ * The user drags the handle, which is below the cursor, but wants to move the
+ * cursor accordingly.
+ *
+ * @param pHandle the rectangle of the handle
+ * @param pEvent the motion event
+ * @param pPoint the computed point (output parameter)
+ */
+void lcl_getDragPoint(GdkRectangle* pHandle, GdkEventButton* pEvent, GdkPoint* pPoint)
+{
+    GdkPoint aCursor, aHandle;
+
+    // Center of the cursor rectangle: we know that it's above the handle.
+    aCursor.x = pHandle->x + pHandle->width / 2;
+    aCursor.y = pHandle->y - pHandle->height / 2;
+    // Center of the handle rectangle.
+    aHandle.x = pHandle->x + pHandle->width / 2;
+    aHandle.y = pHandle->y + pHandle->height / 2;
+    // Our target is the original cursor position + the dragged offset.
+    pPoint->x = aCursor.x + (pEvent->x - aHandle.x);
+    pPoint->y = aCursor.y + (pEvent->y - aHandle.y);
+}
+
 gboolean lcl_signalMotion(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView)
 {
     (void)pEventBox;
     if (pDocView->m_bInDragMiddleHandle)
     {
-        // The user drags the handle, which is below the cursor, but wants to move the cursor accordingly.
-        GdkPoint aCursor, aHandle, aPoint;
+        GdkPoint aPoint;
 
         g_info("lcl_signalMotion: dragging the middle handle");
-        // Center of the cursor rectangle: we know that it's above the handle.
-        aCursor.x = pDocView->m_aHandleMiddleRect.x + pDocView->m_aHandleMiddleRect.width / 2;
-        aCursor.y = pDocView->m_aHandleMiddleRect.y - pDocView->m_aHandleMiddleRect.height / 2;
-        // Center of the handle rectangle.
-        aHandle.x = pDocView->m_aHandleMiddleRect.x + pDocView->m_aHandleMiddleRect.width / 2;
-        aHandle.y = pDocView->m_aHandleMiddleRect.y + pDocView->m_aHandleMiddleRect.height / 2;
-        // Our target is the original cursor position + the dragged offset.
-        aPoint.x = aCursor.x + (pEvent->x - aHandle.x);
-        aPoint.y = aCursor.y + (pEvent->y - aHandle.y);
-
+        lcl_getDragPoint(&pDocView->m_aHandleMiddleRect, pEvent, &aPoint);
         pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
         pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
     }
+    else if (pDocView->m_bInDragEndHandle)
+    {
+        GdkPoint aPoint;
+
+        g_info("lcl_signalMotion: dragging the end handle");
+        lcl_getDragPoint(&pDocView->m_aHandleEndRect, pEvent, &aPoint);
+        pDocView->pDocument->pClass->setTextSelection(pDocView->pDocument, LOK_SETTEXTSELECTION_END, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y));
+    }
     return FALSE;
 }
 
@@ -79,6 +100,12 @@ gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
         pDocView->m_bInDragMiddleHandle = FALSE;
         return FALSE;
     }
+    else if (pDocView->m_bInDragEndHandle && pEvent->type == GDK_BUTTON_RELEASE)
+    {
+        g_info("lcl_signalButton: end of drag end handle");
+        pDocView->m_bInDragEndHandle = FALSE;
+        return FALSE;
+    }
 
     if (pDocView->m_bEdit)
     {
@@ -93,6 +120,12 @@ gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocVi
             pDocView->m_bInDragMiddleHandle = TRUE;
             return FALSE;
         }
+        else if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleEndRect, NULL) && pEvent->type == GDK_BUTTON_PRESS)
+        {
+            g_info("lcl_signalButton: start of drag end handle");
+            pDocView->m_bInDragEndHandle = TRUE;
+            return FALSE;
+        }
     }
 
     lok_docview_set_edit(pDocView, TRUE);
@@ -191,6 +224,8 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_pHandleEnd = NULL;
     memset(&pDocView->m_aHandleMiddleRect, 0, sizeof(pDocView->m_aHandleMiddleRect));
     pDocView->m_bInDragMiddleHandle = FALSE;
+    memset(&pDocView->m_aHandleEndRect, 0, sizeof(pDocView->m_aHandleEndRect));
+    pDocView->m_bInDragEndHandle = FALSE;
 
     gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
                         GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
@@ -332,7 +367,7 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
             // Have a start position: we need an end handle.
             if (!pDocView->m_pHandleEnd)
                 pDocView->m_pHandleEnd = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_end.png");
-            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionEnd, pDocView->m_pHandleEnd, NULL);
+            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionEnd, pDocView->m_pHandleEnd, &pDocView->m_aHandleEndRect);
         }
     }
 
commit 565a9f3fd8333e14497f058f9e4387e511aa36c9
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 17:43:18 2015 +0100

    LOK: add lok::Document::setTextSelection()
    
    What's interesting about this is that it allows adjusting the position
    of both the point and mark of the selection, while the normal UI only
    allows adjusting the point.
    
    Change-Id: If61f57c68c28c67fec252f2b666a706f52dd8d26

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 5a5f609..d7ca143 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -207,6 +207,10 @@ static void doc_postMouseEvent (LibreOfficeKitDocument* pThis,
                                 int nX,
                                 int nY,
                                 int nCount);
+static void doc_setTextSelection (LibreOfficeKitDocument* pThis,
+                                  int nType,
+                                  int nX,
+                                  int nY);
 
 struct LibLODocument_Impl : public _LibreOfficeKitDocument
 {
@@ -235,6 +239,7 @@ struct LibLODocument_Impl : public _LibreOfficeKitDocument
             m_pDocumentClass->initializeForRendering = doc_initializeForRendering;
             m_pDocumentClass->registerCallback = doc_registerCallback;
             m_pDocumentClass->postMouseEvent = doc_postMouseEvent;
+            m_pDocumentClass->setTextSelection = doc_setTextSelection;
 
             gDocumentClass = m_pDocumentClass;
         }
@@ -673,6 +678,17 @@ static void doc_postMouseEvent(LibreOfficeKitDocument* pThis, int nType, int nX,
     pDoc->postMouseEvent(nType, nX, nY, nCount);
 }
 
+static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
+{
+    ITiledRenderable* pDoc = getTiledRenderable(pThis);
+    if (!pDoc)
+    {
+        gImpl->maLastExceptionMsg = "Document doesn't support tiled rendering";
+        return;
+    }
+
+    pDoc->setTextSelection(nType, nX, nY);
+}
 
 static char* lo_getError (LibreOfficeKit *pThis)
 {
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 2044795..eccf19b 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -117,6 +117,15 @@ typedef enum
 }
 LibreOfficeKitMouseEventType;
 
+typedef enum
+{
+    /// The start of selection is to be adjusted.
+    LOK_SETTEXTSELECTION_START,
+    /// The end of selection is to be adjusted.
+    LOK_SETTEXTSELECTION_END
+}
+LibreOfficeKitSetTextSelectionType;
+
 typedef void (*LibreOfficeKitCallback)(int nType, const char* pPayload, void* pData);
 #endif // LOK_USE_UNSTABLE_API
 
@@ -204,6 +213,11 @@ struct _LibreOfficeKitDocumentClass
                          int nX,
                          int nY,
                          int nCount);
+  /// @see lok::Document::setTextSelection
+  void (*setTextSelection)(LibreOfficeKitDocument* pThis,
+                         int nType,
+                         int nX,
+                         int nY);
 #endif // LOK_USE_UNSTABLE_API
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 8448fcd..ef365ce 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -117,6 +117,18 @@ public:
     {
         mpDoc->pClass->postMouseEvent(mpDoc, nType, nX, nY, nCount);
     }
+
+    /**
+     * Sets the start or end of a text selection.
+     *
+     * @param nType @see LibreOfficeKitSetTextSelectionType
+     * @param nX horizontal position in document coordinates
+     * @param nY vertical position in document coordinates
+     */
+    inline void setTextSelection(int nType, int nX, int nY)
+    {
+        mpDoc->pClass->setTextSelection(mpDoc, nType, nX, nY);
+    }
 #endif // LOK_USE_UNSTABLE_API
 };
 
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index 9edd7a1..d5b3e80 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -107,6 +107,13 @@ public:
      * @see lok::Document::postMouseEvent().
      */
     virtual void postMouseEvent(int /*nType*/, int /*nX*/, int /*nY*/, int /*nCount*/) { }
+
+    /**
+     * Sets the start or end of a text selection.
+     *
+     * @see lok::Document::setTextSelection().
+     */
+    virtual void setTextSelection(int /*nType*/, int /*nX*/, int /*nY*/) { }
 };
 
 } // namespace vcl
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 894a127..6ffa02f 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -415,6 +415,8 @@ public:
     virtual void registerCallback(LibreOfficeKitCallback pCallback, void* pData) SAL_OVERRIDE;
     /// @see vcl::ITiledRenderable::postMouseEvent().
     virtual void postMouseEvent(int nType, int nX, int nY, int nCount) SAL_OVERRIDE;
+    /// @see vcl::ITiledRenderable::setTextSelection().
+    virtual void setTextSelection(int nType, int nX, int nY) SAL_OVERRIDE;
 
     void                        Invalidate();
     void                        Reactivate(SwDocShell* pNewDocShell);
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 6666249..bb59217 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -6256,4 +6256,18 @@ void SwEditWin::LogicMouseButtonUp(const MouseEvent& rMouseEvent)
     MouseButtonUp(rMouseEvent);
 }
 
+void SwEditWin::SetCursorLogicPosition(bool bPoint, const Point& rPosition)
+{
+    // Not an SwWrtShell, as that would make SwCrsrShell::GetCrsr() inaccessible.
+    SwEditShell& rShell = m_rView.GetWrtShell();
+    SwMvContext aMvContext(&rShell);
+    // If the mark is to be updated, then exchange the point and mark before
+    // and after, as we can't easily set the mark.
+    if (!bPoint)
+        rShell.GetCrsr()->Exchange();
+    rShell.SetCrsr(rPosition);
+    if (!bPoint)
+        rShell.GetCrsr()->Exchange();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index 5557321..9af9446 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -305,6 +305,8 @@ public:
     void LogicMouseButtonDown(const MouseEvent& rMouseEvent);
     /// Same as MouseButtonUp(), but coordinates are in logic unit.
     void LogicMouseButtonUp(const MouseEvent& rMouseEvent);
+    /// Allows adjusting the point or mark of the selection to a document coordinate.
+    void SetCursorLogicPosition(bool bPoint, const Point& rPosition);
 };
 
 #endif
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 70abbac..3a98cd9 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3194,6 +3194,25 @@ void SwXTextDocument::postMouseEvent(int nType, int nX, int nY, int nCount)
     }
 }
 
+void SwXTextDocument::setTextSelection(int nType, int nX, int nY)
+{
+    SolarMutexGuard aGuard;
+
+    SwEditWin& rEditWin = pDocShell->GetView()->GetEditWin();
+    switch (nType)
+    {
+    case LOK_SETTEXTSELECTION_START:
+        rEditWin.SetCursorLogicPosition(/*bPoint=*/false, Point(nX, nY));
+        break;
+    case LOK_SETTEXTSELECTION_END:
+        rEditWin.SetCursorLogicPosition(/*bPoint=*/true, Point(nX, nY));
+        break;
+    default:
+        assert(false);
+        break;
+    }
+}
+
 void * SAL_CALL SwXTextDocument::operator new( size_t t) throw()
 {
     return SwXTextDocumentBaseClass::operator new(t);
commit 0135d5d5c2a41bc306062334db731b98438a6caf
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 14:15:42 2015 +0100

    lokdocview: allow dragging the middle handle
    
    Change-Id: I83ef2797c17c8de8f8e9b5f3dcbe9adb34eb4313

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index d3e663d..95288cd 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -60,6 +60,10 @@ struct _LOKDocView
     cairo_surface_t* m_pHandleStart;
     /// Bitmap of the text selection middle handle.
     cairo_surface_t* m_pHandleMiddle;
+    /// Rectangle of the text selection middle handle, to know if the user clicked on it or not
+    GdkRectangle m_aHandleMiddleRect;
+    /// If we are in the middle of a drag of the text selection middle handle.
+    gboolean m_bInDragMiddleHandle;
     /// Bitmap of the text selection end handle.
     cairo_surface_t* m_pHandleEnd;
 };
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 44f0d87..0fa3e11 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -42,12 +42,59 @@ void lcl_onDestroy( LOKDocView* pDocView, gpointer pData )
     pDocView->pDocument = NULL;
 }
 
+gboolean lcl_signalMotion(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView)
+{
+    (void)pEventBox;
+    if (pDocView->m_bInDragMiddleHandle)
+    {
+        // The user drags the handle, which is below the cursor, but wants to move the cursor accordingly.
+        GdkPoint aCursor, aHandle, aPoint;
+
+        g_info("lcl_signalMotion: dragging the middle handle");
+        // Center of the cursor rectangle: we know that it's above the handle.
+        aCursor.x = pDocView->m_aHandleMiddleRect.x + pDocView->m_aHandleMiddleRect.width / 2;
+        aCursor.y = pDocView->m_aHandleMiddleRect.y - pDocView->m_aHandleMiddleRect.height / 2;
+        // Center of the handle rectangle.
+        aHandle.x = pDocView->m_aHandleMiddleRect.x + pDocView->m_aHandleMiddleRect.width / 2;
+        aHandle.y = pDocView->m_aHandleMiddleRect.y + pDocView->m_aHandleMiddleRect.height / 2;
+        // Our target is the original cursor position + the dragged offset.
+        aPoint.x = aCursor.x + (pEvent->x - aHandle.x);
+        aPoint.y = aCursor.y + (pEvent->y - aHandle.y);
+
+        pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONDOWN, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
+        pDocView->pDocument->pClass->postMouseEvent(pDocView->pDocument, LOK_MOUSEEVENT_MOUSEBUTTONUP, pixelToTwip(aPoint.x), pixelToTwip(aPoint.y), 1);
+    }
+    return FALSE;
+}
+
 /// Receives a button press event.
-void lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView)
+gboolean lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView* pDocView)
 {
     g_info("lcl_signalButton: %d, %d (in twips: %d, %d)", (int)pEvent->x, (int)pEvent->y, (int)pixelToTwip(pEvent->x), (int)pixelToTwip(pEvent->y));
     (void) pEventBox;
 
+    if (pDocView->m_bInDragMiddleHandle && pEvent->type == GDK_BUTTON_RELEASE)
+    {
+        g_info("lcl_signalButton: end of drag middle handle");
+        pDocView->m_bInDragMiddleHandle = FALSE;
+        return FALSE;
+    }
+
+    if (pDocView->m_bEdit)
+    {
+        GdkRectangle aClick;
+        aClick.x = pEvent->x;
+        aClick.y = pEvent->y;
+        aClick.width = 1;
+        aClick.height = 1;
+        if (gdk_rectangle_intersect(&aClick, &pDocView->m_aHandleMiddleRect, NULL) && pEvent->type == GDK_BUTTON_PRESS)
+        {
+            g_info("lcl_signalButton: start of drag middle handle");
+            pDocView->m_bInDragMiddleHandle = TRUE;
+            return FALSE;
+        }
+    }
+
     lok_docview_set_edit(pDocView, TRUE);
 
     switch (pEvent->type)
@@ -73,6 +120,7 @@ void lcl_signalButton(GtkWidget* pEventBox, GdkEventButton* pEvent, LOKDocView*
     default:
         break;
     }
+    return FALSE;
 }
 
 SAL_DLLPUBLIC_EXPORT guint lok_docview_get_type()
@@ -115,8 +163,10 @@ static void lok_docview_init( LOKDocView* pDocView )
     gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(pDocView),
                                            pDocView->pEventBox );
 
+    gtk_widget_set_events(pDocView->pEventBox, GDK_BUTTON_PRESS_MASK); // So that drag doesn't try to move the whole window.
     gtk_signal_connect(GTK_OBJECT(pDocView->pEventBox), "button-press-event", GTK_SIGNAL_FUNC(lcl_signalButton), pDocView);
     gtk_signal_connect(GTK_OBJECT(pDocView->pEventBox), "button-release-event", GTK_SIGNAL_FUNC(lcl_signalButton), pDocView);
+    gtk_signal_connect(GTK_OBJECT(pDocView->pEventBox), "motion-notify-event", GTK_SIGNAL_FUNC(lcl_signalMotion), pDocView);
 
     gtk_widget_show( pDocView->pEventBox );
 
@@ -139,6 +189,8 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_pHandleStart = NULL;
     pDocView->m_pHandleMiddle = NULL;
     pDocView->m_pHandleEnd = NULL;
+    memset(&pDocView->m_aHandleMiddleRect, 0, sizeof(pDocView->m_aHandleMiddleRect));
+    pDocView->m_bInDragMiddleHandle = FALSE;
 
     gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
                         GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
@@ -191,7 +243,7 @@ static gboolean lcl_handleTimeout(gpointer pData)
 }
 
 /// Renders pHandle below a pCursor rectangle on pCairo.
-static void lcl_renderHandle(cairo_t* pCairo, GdkRectangle* pCursor, cairo_surface_t* pHandle)
+static void lcl_renderHandle(cairo_t* pCairo, GdkRectangle* pCursor, cairo_surface_t* pHandle, GdkRectangle* pRectangle)
 {
     GdkPoint aCursorBottom;
     int nHandleWidth, nHandleHeight;
@@ -210,6 +262,15 @@ static void lcl_renderHandle(cairo_t* pCairo, GdkRectangle* pCursor, cairo_surfa
     cairo_set_source_surface(pCairo, pHandle, 0, 0);
     cairo_paint(pCairo);
     cairo_restore(pCairo);
+
+    if (pRectangle)
+    {
+        // Return the rectangle that contains the rendered handle.
+        pRectangle->x = aCursorBottom.x;
+        pRectangle->y = aCursorBottom.y;
+        pRectangle->width = nHandleWidth * fHandleScale;
+        pRectangle->height = nHandleHeight * fHandleScale;
+    }
 }
 
 static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpointer pData)
@@ -242,7 +303,7 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
         // Have a cursor, but no selection: we need the middle handle.
         if (!pDocView->m_pHandleMiddle)
             pDocView->m_pHandleMiddle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_middle.png");
-        lcl_renderHandle(pCairo, &pDocView->m_aVisibleCursor, pDocView->m_pHandleMiddle);
+        lcl_renderHandle(pCairo, &pDocView->m_aVisibleCursor, pDocView->m_pHandleMiddle, &pDocView->m_aHandleMiddleRect);
     }
 
     if (pDocView->m_pTextSelectionRectangles)
@@ -264,14 +325,14 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
             // Have a start position: we need a start handle.
             if (!pDocView->m_pHandleStart)
                 pDocView->m_pHandleStart = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_start.png");
-            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionStart, pDocView->m_pHandleStart);
+            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionStart, pDocView->m_pHandleStart, NULL);
         }
         if (!lcl_isEmptyRectangle(&pDocView->m_aTextSelectionEnd))
         {
             // Have a start position: we need an end handle.
             if (!pDocView->m_pHandleEnd)
                 pDocView->m_pHandleEnd = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_end.png");
-            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionEnd, pDocView->m_pHandleEnd);
+            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionEnd, pDocView->m_pHandleEnd, NULL);
         }
     }
 
commit 13de1b87b80fede4179a56f720534f64a74a15c7
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 11:41:59 2015 +0100

    lokdocview: avoid loading the handle bitmaps again and again
    
    Change-Id: I767a1c0ddce4e06d421b6bb951aa6d0451943f89

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index 04d61ad..d3e663d 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -52,8 +52,16 @@ struct _LOKDocView
     guint32 m_nLastButtonReleaseTime;
     /// Rectangles of the current text selection.
     GList* m_pTextSelectionRectangles;
+    /// Position and size of the selection start (as if there would be a cursor caret there).
     GdkRectangle m_aTextSelectionStart;
+    /// Position and size of the selection end.
     GdkRectangle m_aTextSelectionEnd;
+    /// Bitmap of the text selection start handle.
+    cairo_surface_t* m_pHandleStart;
+    /// Bitmap of the text selection middle handle.
+    cairo_surface_t* m_pHandleMiddle;
+    /// Bitmap of the text selection end handle.
+    cairo_surface_t* m_pHandleEnd;
 };
 
 struct _LOKDocViewClass
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 89feeca..44f0d87 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -136,6 +136,9 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_pTextSelectionRectangles = NULL;
     memset(&pDocView->m_aTextSelectionStart, 0, sizeof(pDocView->m_aTextSelectionStart));
     memset(&pDocView->m_aTextSelectionEnd, 0, sizeof(pDocView->m_aTextSelectionEnd));
+    pDocView->m_pHandleStart = NULL;
+    pDocView->m_pHandleMiddle = NULL;
+    pDocView->m_pHandleEnd = NULL;
 
     gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
                         GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
@@ -237,9 +240,9 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
     if (!lcl_isEmptyRectangle(&pDocView->m_aVisibleCursor) && !pDocView->m_pTextSelectionRectangles)
     {
         // Have a cursor, but no selection: we need the middle handle.
-        cairo_surface_t* pHandle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_middle.png");
-        lcl_renderHandle(pCairo, &pDocView->m_aVisibleCursor, pHandle);
-        cairo_surface_destroy(pHandle);
+        if (!pDocView->m_pHandleMiddle)
+            pDocView->m_pHandleMiddle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_middle.png");
+        lcl_renderHandle(pCairo, &pDocView->m_aVisibleCursor, pDocView->m_pHandleMiddle);
     }
 
     if (pDocView->m_pTextSelectionRectangles)
@@ -259,16 +262,16 @@ static gboolean renderOverlay(GtkWidget* pWidget, GdkEventExpose* pEvent, gpoint
         if (!lcl_isEmptyRectangle(&pDocView->m_aTextSelectionStart))
         {
             // Have a start position: we need a start handle.
-            cairo_surface_t* pHandle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_start.png");
-            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionStart, pHandle);
-            cairo_surface_destroy(pHandle);
+            if (!pDocView->m_pHandleStart)
+                pDocView->m_pHandleStart = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_start.png");
+            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionStart, pDocView->m_pHandleStart);
         }
         if (!lcl_isEmptyRectangle(&pDocView->m_aTextSelectionEnd))
         {
             // Have a start position: we need an end handle.
-            cairo_surface_t* pHandle = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_end.png");
-            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionEnd, pHandle);
-            cairo_surface_destroy(pHandle);
+            if (!pDocView->m_pHandleEnd)
+                pDocView->m_pHandleEnd = cairo_image_surface_create_from_png(CURSOR_HANDLE_DIR "handle_end.png");
+            lcl_renderHandle(pCairo, &pDocView->m_aTextSelectionEnd, pDocView->m_pHandleEnd);
         }
     }
 
commit 2e70fa6968bd77bca3a21685974c869d55f79dec
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Tue Feb 10 11:05:58 2015 +0100

    android: optipng the resources.
    
    Change-Id: I2b27c6edd94d63ddcfb885592b0fb954cf505e8b

diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_img.png b/android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_img.png
index ab8487a..fd234f3 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_img.png and b/android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_img.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_split_img.png b/android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_split_img.png
index 4c780ea..84d3660 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_split_img.png and b/android/experimental/LOAndroid3/res/drawable-hdpi/bg_striped_split_img.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/light_view_as_grid.png b/android/experimental/LOAndroid3/res/drawable-hdpi/light_view_as_grid.png
index ae138ed..99301de 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/light_view_as_grid.png and b/android/experimental/LOAndroid3/res/drawable-hdpi/light_view_as_grid.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/lo_icon.png b/android/experimental/LOAndroid3/res/drawable-hdpi/lo_icon.png
index 2ef8641..8c6b699 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/lo_icon.png and b/android/experimental/LOAndroid3/res/drawable-hdpi/lo_icon.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-ldpi/lo_icon.png b/android/experimental/LOAndroid3/res/drawable-ldpi/lo_icon.png
index 95b3113..41a7114 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-ldpi/lo_icon.png and b/android/experimental/LOAndroid3/res/drawable-ldpi/lo_icon.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/background.png b/android/experimental/LOAndroid3/res/drawable-mdpi/background.png
index 611592b..5605870 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/background.png and b/android/experimental/LOAndroid3/res/drawable-mdpi/background.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_img.png b/android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_img.png
index 06e3ebd..4bbd703 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_img.png and b/android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_img.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_split_img.png b/android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_split_img.png
index 1308ade..3415ac1 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_split_img.png and b/android/experimental/LOAndroid3/res/drawable-mdpi/bg_striped_split_img.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/lo_icon.png b/android/experimental/LOAndroid3/res/drawable-mdpi/lo_icon.png
index 4f3f89b..569808e 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/lo_icon.png and b/android/experimental/LOAndroid3/res/drawable-mdpi/lo_icon.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/shadow.png b/android/experimental/LOAndroid3/res/drawable-mdpi/shadow.png
index 3ce69155..c696a2c 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/shadow.png and b/android/experimental/LOAndroid3/res/drawable-mdpi/shadow.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_img.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_img.png
index 92f3fa1..79b9ffd 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_img.png and b/android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_img.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_split_img.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_split_img.png
index e31f4a6..8e68c98 100644
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_split_img.png and b/android/experimental/LOAndroid3/res/drawable-xhdpi/bg_striped_split_img.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable/calc.png b/android/experimental/LOAndroid3/res/drawable/calc.png
index a3f5fd4..0c0d314 100644
Binary files a/android/experimental/LOAndroid3/res/drawable/calc.png and b/android/experimental/LOAndroid3/res/drawable/calc.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable/dummy_page.png b/android/experimental/LOAndroid3/res/drawable/dummy_page.png
index c58d276..31a0756 100644
Binary files a/android/experimental/LOAndroid3/res/drawable/dummy_page.png and b/android/experimental/LOAndroid3/res/drawable/dummy_page.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable/folder.png b/android/experimental/LOAndroid3/res/drawable/folder.png
index 9c9b42c..40a6598 100644
Binary files a/android/experimental/LOAndroid3/res/drawable/folder.png and b/android/experimental/LOAndroid3/res/drawable/folder.png differ
diff --git a/android/experimental/LOAndroid3/res/drawable/writer.png b/android/experimental/LOAndroid3/res/drawable/writer.png
index 2f4abcb..8a4e21e 100644
Binary files a/android/experimental/LOAndroid3/res/drawable/writer.png and b/android/experimental/LOAndroid3/res/drawable/writer.png differ
commit baa5459359c7c92ad08059f4a5e8b781be645c5f
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Tue Feb 10 10:50:52 2015 +0100

    android: Remove duplicated icons.
    
    No need to provide eg. drawable-hdpi/blah.png when it is the same as
    drawable/blah.png anyway.
    
    Change-Id: I4f840a7674e86a7c16d43fc5e1d4fd1e0956d0c8

diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/calc.png b/android/experimental/LOAndroid3/res/drawable-hdpi/calc.png
deleted file mode 100644
index a3f5fd4..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/calc.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/draw.png b/android/experimental/LOAndroid3/res/drawable-hdpi/draw.png
deleted file mode 100644
index b3ee114..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/draw.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/dummy_page.png b/android/experimental/LOAndroid3/res/drawable-hdpi/dummy_page.png
deleted file mode 100644
index c58d276..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/dummy_page.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/impress.png b/android/experimental/LOAndroid3/res/drawable-hdpi/impress.png
deleted file mode 100644
index 5909f05..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/impress.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/calc.png b/android/experimental/LOAndroid3/res/drawable-mdpi/calc.png
deleted file mode 100644
index a3f5fd4..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/calc.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/draw.png b/android/experimental/LOAndroid3/res/drawable-mdpi/draw.png
deleted file mode 100644
index b3ee114..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/draw.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/impress.png b/android/experimental/LOAndroid3/res/drawable-mdpi/impress.png
deleted file mode 100644
index 5909f05..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/impress.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/writer.png b/android/experimental/LOAndroid3/res/drawable-mdpi/writer.png
deleted file mode 100644
index 2f4abcb..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/writer.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/calc.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/calc.png
deleted file mode 100644
index a3f5fd4..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/calc.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/draw.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/draw.png
deleted file mode 100644
index b3ee114..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/draw.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/impress.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/impress.png
deleted file mode 100644
index 5909f05..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/impress.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/writer.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/writer.png
deleted file mode 100644
index 2f4abcb..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/writer.png and /dev/null differ
commit f36302e41da326f8177e4c0e2052ef169ca13d6a
Author: Jan Holesovsky <kendy at collabora.com>
Date:   Tue Feb 10 10:49:12 2015 +0100

    android: Remove unused icons.
    
    Change-Id: Ia844806ad3bff92fcace2765fb3b39ab729a6b28

diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/base.png b/android/experimental/LOAndroid3/res/drawable-hdpi/base.png
deleted file mode 100644
index 729dbcd..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/base.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_compose.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_compose.png
deleted file mode 100644
index cdb09e4..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_compose.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_compose_inverse.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_compose_inverse.png
deleted file mode 100644
index 8a0c487..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_compose_inverse.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_launcher.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 96a442e..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_launcher_settings.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_launcher_settings.png
deleted file mode 100644
index c02bd42..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_launcher_settings.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_magnifying_glass.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_magnifying_glass.png
deleted file mode 100644
index cdf3518..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_magnifying_glass.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_refresh.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_refresh.png
deleted file mode 100644
index 08c32e0..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_refresh.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_refresh_inverse.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_refresh_inverse.png
deleted file mode 100644
index 9ab1d38..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_refresh_inverse.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_search.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_search.png
deleted file mode 100644
index 59de344..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_search.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_search_inverse.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_search_inverse.png
deleted file mode 100644
index eb090a6..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_search_inverse.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_status_logo.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_status_logo.png
deleted file mode 100644
index d5f1669..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_status_logo.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_title_share_default.png b/android/experimental/LOAndroid3/res/drawable-hdpi/ic_title_share_default.png
deleted file mode 100644
index ee4b285..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/ic_title_share_default.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/icon.png b/android/experimental/LOAndroid3/res/drawable-hdpi/icon.png
deleted file mode 100644
index 723fbf0..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/icon.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/light_sort_by_size.png b/android/experimental/LOAndroid3/res/drawable-hdpi/light_sort_by_size.png
deleted file mode 100644
index 3b34aaf..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/light_sort_by_size.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/math.png b/android/experimental/LOAndroid3/res/drawable-hdpi/math.png
deleted file mode 100644
index 50b8dc8..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/math.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-hdpi/startcenter.png b/android/experimental/LOAndroid3/res/drawable-hdpi/startcenter.png
deleted file mode 100644
index 7e8e2a0..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-hdpi/startcenter.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-ldpi/ic_launcher.png b/android/experimental/LOAndroid3/res/drawable-ldpi/ic_launcher.png
deleted file mode 100644
index 1095584..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-ldpi/ic_launcher.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-ldpi/icon.png b/android/experimental/LOAndroid3/res/drawable-ldpi/icon.png
deleted file mode 100644
index 181f679..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-ldpi/icon.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/base.png b/android/experimental/LOAndroid3/res/drawable-mdpi/base.png
deleted file mode 100644
index 729dbcd..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/base.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_compose.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_compose.png
deleted file mode 100644
index 15a4130..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_compose.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_compose_inverse.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_compose_inverse.png
deleted file mode 100644
index de58ce8..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_compose_inverse.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_launcher.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 359047d..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_launcher_settings.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_launcher_settings.png
deleted file mode 100644
index 05cdd9a..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_launcher_settings.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_magnifying_glass.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_magnifying_glass.png
deleted file mode 100644
index 53aa6d9..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_magnifying_glass.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_refresh.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_refresh.png
deleted file mode 100644
index 55c43c3..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_refresh.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_refresh_inverse.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_refresh_inverse.png
deleted file mode 100644
index d5736ec..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_refresh_inverse.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_search.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_search.png
deleted file mode 100644
index 75339d9..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_search.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_search_inverse.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_search_inverse.png
deleted file mode 100644
index b462c32..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_search_inverse.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_status_logo.png b/android/experimental/LOAndroid3/res/drawable-mdpi/ic_status_logo.png
deleted file mode 100644
index 835fc92..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/ic_status_logo.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-mdpi/icon.png b/android/experimental/LOAndroid3/res/drawable-mdpi/icon.png
deleted file mode 100644
index 79f50d8..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-mdpi/icon.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/base.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/base.png
deleted file mode 100644
index 729dbcd..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/base.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_launcher.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 71c6d76..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_launcher_settings.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_launcher_settings.png
deleted file mode 100644
index 2b2907b..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_launcher_settings.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_status_logo.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_status_logo.png
deleted file mode 100644
index c800542..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/ic_status_logo.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xhdpi/icon.png b/android/experimental/LOAndroid3/res/drawable-xhdpi/icon.png
deleted file mode 100644
index 34ca9a4..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xhdpi/icon.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable-xxhdpi/ic_launcher.png b/android/experimental/LOAndroid3/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100644
index 4df1894..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/android/experimental/LOAndroid3/res/drawable/base.png b/android/experimental/LOAndroid3/res/drawable/base.png
deleted file mode 100644
index 729dbcd..0000000
Binary files a/android/experimental/LOAndroid3/res/drawable/base.png and /dev/null differ
commit e07d9c084b5487eb38810002f8512bb6268cdc1d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Tue Feb 10 11:10:50 2015 +0100

    lokdocview: draw handles at selection start/end
    
    Change-Id: Ic9b4138619f20a8d35437912784b94f4d1f2af4f

diff --git a/include/LibreOfficeKit/LibreOfficeKitGtk.h b/include/LibreOfficeKit/LibreOfficeKitGtk.h
index def92f9..04d61ad 100644
--- a/include/LibreOfficeKit/LibreOfficeKitGtk.h
+++ b/include/LibreOfficeKit/LibreOfficeKitGtk.h
@@ -52,6 +52,8 @@ struct _LOKDocView
     guint32 m_nLastButtonReleaseTime;
     /// Rectangles of the current text selection.
     GList* m_pTextSelectionRectangles;
+    GdkRectangle m_aTextSelectionStart;
+    GdkRectangle m_aTextSelectionEnd;
 };
 
 struct _LOKDocViewClass
diff --git a/libreofficekit/source/gtk/lokdocview.c b/libreofficekit/source/gtk/lokdocview.c
index 351c7cc..89feeca 100644
--- a/libreofficekit/source/gtk/lokdocview.c
+++ b/libreofficekit/source/gtk/lokdocview.c
@@ -134,6 +134,8 @@ static void lok_docview_init( LOKDocView* pDocView )
     pDocView->m_nLastButtonPressTime = 0;
     pDocView->m_nLastButtonReleaseTime = 0;
     pDocView->m_pTextSelectionRectangles = NULL;
+    memset(&pDocView->m_aTextSelectionStart, 0, sizeof(pDocView->m_aTextSelectionStart));
+    memset(&pDocView->m_aTextSelectionEnd, 0, sizeof(pDocView->m_aTextSelectionEnd));
 
     gtk_signal_connect( GTK_OBJECT(pDocView), "destroy",
                         GTK_SIGNAL_FUNC(lcl_onDestroy), NULL );
@@ -185,6 +187,28 @@ static gboolean lcl_handleTimeout(gpointer pData)

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list