AddNewCursors

From Wiki.ooo4kids.org
Jump to: navigation, search


Add New Cursors


All the changes added to the original OpenOffice.org source code provided in this page, are :

  • Copyright Eric Bachard January 2010
  • Under LGPLv3 license ( and you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation)


Important: If you use this information, don't forget everything you'll find here is under CC by-sa License, and you must mention your sources in what you write ...


Thanks to Ben Bois for the nice cursors he provided

Additional note: once some known issues will be solved (mostly due to the eraser behavior), a backport should be proposed into OpenOffice.org, to improve the extra presenter features.


Introduction

Below, you'll find a technical description describing how to add new cursors in OOo4Kids. It is question of OpenOffice.org source code (mainly C++ and some objective C on Mac OS X), e.g. the internal source code organisation in OpenOffice.org, like with the graphical part aka vcl (Visual Class Libraries), the Office API (aka offapi) where we'll add new constant for the new cursor "Eraser". The description will concern all operating systems, but when something specific to one of them will be needed, this will be mentionned.

The pre-requisites to read this article still have to be defined, but if the reader is not used with some notions, we invite him to have a look at the OpenOffice.org wiki to complete his knowledge, and read this article in the best conditions.

Idea

Tip : to set the pen mode, in Impress, in the main menu, select " Slideshow -> Slide Show Settings ...". A dialog box will open. Then enable the pen mode in Impress, selecting the options as shown in the red ellipse

The new feature will be based on the current annotation mode in Impress.

Prerequisite : "Mouse pointer visible", and "Mouse pointer as a pen" must be enabled in your presentation. The code around that, has been written by students from Ecole Centrale Nantes (under OpenOffice.org Education Project applications), and has been integrated into OpenOffice.org. So far, only go-oo and OOo4Kids have the feature enabled by default to my knowledge. If this pre-condition is ok, then, the "pen feature" must be visible and available in presentation mode.

e.g. : the new eraser cursor look below :

Cursor-Eraser-64.png

Common part

In this part, will be described the common changes, for all operating systems, and a short description of the changes in slideshow will be added, to introduce how things work in Impress.

Concerned modules

  • offapi : Impress is an UNO product, so we need to introduce a new constant in the interface, thus the cursor will exist for Impress in offapi/com/sun/star/awt/SystemPointer.idl
	//------------------------------------------------------------------------- 
		
	/** specifies a mouse pointer which symbolizes an eraser.
	 */
	const long ERASER = 94; 


  • vcl : we need to add the new cursor in the interface, and change the cursor count (if wrong, the build will break anyway).
#ifdef OOo4Kids
#define POINTER_ERASER              ((PointerStyle)94)
#define POINTER_COUNT                   95
#else
#define POINTER_COUNT                   94
  • slideshow : we need to use the eraser cursor in annotations mode.

Select eraser mode.png

Mac OS X only

On Mac OS X, the cursors are managed in vcl, more precisely in vcl/aqua, the implemented part of vcl.


  • vcl/aqua :
    • add the cursor as .png in vcl/aqua/source/res/cursors
    • modify the list + the hotspot value to make it match with the new cursor in vcl/aqua/source/app/saldata.cxx
  • vcl/aqua/source/app/saldata.cxx
    • add the eraser96 cursor in the array containing all existing cursors used on Mac OS X.
const aCursorTab[ POINTER_COUNT ] = 
{ 

....


{ "pntbrsh", { 9, 16 } },  //POINTER_PAINTBRUSH 93                                                                
{ "eraser96", { 19, 37 } }  //POINTER_ERASER 94                                                                   
};                                                                                                                

Note: the first part is a hack to add the big arrow cursor on Mac OS X. Please, notice the hotspot coordinates, who must be adapted to the cursor.

const aCursorTab[ POINTER_COUNT ] = 
{                                                                                                                 
#ifdef OOo4Kids                                                                                                   
{ "arrow", { 16, 12 } }, //POINTER_ARROW  0                                                                       
#else                                                                                                             
{ NULL, { 0, 0 } }, //POINTER_ARROW                                                                               
#endif 

The second important part of the hack is to undefine the arrow cursor in vcl/aqua/source/window/salframe.cxx, thus the big arrow will replace it (when NULL, the system arrow pointer is the fallback, but we provide our own arrow pointer, who is basicaly a big arrow pointer instead)

NSCursor* AquaSalFrame::getCurrentCursor() const                                                                  
{                                                                                                                 
    NSCursor* pCursor = nil;                                                                                      
    switch( mePointerStyle )                                                                                      
    {                                                                                                             
    case POINTER_TEXT:      pCursor = [NSCursor IBeamCursor];           break;                                    
    case POINTER_CROSS:     pCursor = [NSCursor crosshairCursor];       break;                                    
    case POINTER_HAND:                                                                                            
    case POINTER_MOVE:      pCursor = [NSCursor openHandCursor];        break;                                    
    case POINTER_NSIZE:     pCursor = [NSCursor resizeUpCursor];        break;                                    
    case POINTER_SSIZE:     pCursor = [NSCursor resizeDownCursor];      break;                                    
    case POINTER_ESIZE:     pCursor = [NSCursor resizeRightCursor];      break;                                   
    case POINTER_WSIZE:     pCursor = [NSCursor resizeLeftCursor];     break;                                     
#ifndef OOo4Kids                                                                                                  
    case POINTER_ARROW:     pCursor = [NSCursor arrowCursor];           break;                                    
#endif                                                                                                            

That's all for Mac OS X !! And the eraser cursor will be used if requested by any application (e.g. slideshow).

Windows only

The Windows stuff is in vcl/win

  • vcl/win/source/src (ressources) :

The cursor is a bitmap with .cur extension, for instance eraser96.cur, and containing several images. On Windows XP (means in OpenOffice.org too), the cursor must be a 32x32 image, and one of the contained image must be 2 colors only. FIXME : why ?

Extremely important : the hotspot must be correctly adjusted. Tested : in some cases, where the hotspot is not correct, the cursor may even not appear !!


Same directory, in the resource file, add a new constant, matching with the cursor name (ARROW96.CUR)

Index: vcl/win/source/src/salsrc.rc
===================================================================
--- vcl/win/source/src/salsrc.rc	(revision 453)
+++ vcl/win/source/src/salsrc.rc	(working copy)
@@ -118,6 +118,7 @@
 SAL_RESID_POINTER_TAB_SELECT_W          CURSOR          TBLSELW.CUR
 SAL_RESID_POINTER_TAB_SELECT_SW         CURSOR          TBLSELSW.CUR
SAL_RESID_POINTER_PAINTBRUSH            CURSOR          PNTBRSH.CUR
+SAL_RESID_POINTER_ERASER            	CURSOR          ERASER96.CUR
 
 SAL_RESID_BITMAP_50                             BITMAP          50.BMP

Of course, add the new cursor in the makefile, to be builtin, and contained in the libvclmi.dll

                        tblselsw.cur                     \
                        pntbrsh.cur                  \
			eraser96.cur			\
                        50.bmp                          \
			sd.ico
 


Plus add the constant in the array ( in vcl/win/source/window/salframe.cxx )

   // --> FME 2004-08-16 #i20119# Paintbrush tool
    { 0, 0, SAL_RESID_POINTER_PAINTBRUSH },          // POINTER_PAINTBRUSH 93
    // <--

    { 0, 0, SAL_RESID_POINTER_ERASER }          // POINTER_ERASER 94

Define the constant value :

Index: vcl/win/inc/salids.hrc
--- vcl/win/inc/salids.hrc	(revision 453)
+++ vcl/win/inc/salids.hrc	(working copy)
@@ -115,6 +115,7 @@
 #define SAL_RESID_POINTER_TAB_SELECT_W                          10076
 #define SAL_RESID_POINTER_TAB_SELECT_SW                         10077
 #define SAL_RESID_POINTER_PAINTBRUSH                            10078
+#define SAL_RESID_POINTER_ERASER					10079
 
 #define SAL_RESID_BITMAP_50                                             11000
 

That's all for Windows !! And the cursor if selected somewhere in OpenOffice.org will be provided at low level by the libvclmi.dll

Linux only

without gtk

On Linux, the cursors, must be provided as sources files, compiled and loaded at runtime in vcl/win/source/app/saldisplay.cxx, as described below.


// Pointer                                                                                                        
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=                                   
#define MAKE_BITMAP( name ) \                                                                                     
    XCreateBitmapFromData( pDisp_, \                                                                              
                           DefaultRootWindow( pDisp_ ), \                                                         
                           name##_bits, \                                                                         
                           name##_width, \                                                                        
                           name##_height )                                                                        
                                                                                                                  
#define MAKE_CURSOR( name ) \                                                                                     
    aCursBitmap = MAKE_BITMAP( name##curs ); \                                                                    
    aMaskBitmap = MAKE_BITMAP( name##mask ); \                                                                    
    nXHot = name##curs_x_hot; \                                                                                   
    nYHot = name##curs_y_hot 

And later, use it :

XLIB_Cursor SalDisplay::GetPointer( int ePointerStyle )
{
    if( ePointerStyle >= POINTER_COUNT )
        return 0;

    XLIB_Cursor &aCur = aPointerCache_[ePointerStyle];

    if( aCur != None )
        return aCur;

    Pixmap          aCursBitmap = None, aMaskBitmap = None;
    unsigned int    nXHot = 0, nYHot = 0;

    switch( ePointerStyle )
    {
// OOo4Kids : hack the big arrow ?
		case POINTER_NULL:
 
....

	case POINTER_ERASER:
	    MAKE_CURSOR( eraser96_ );



To create a new cursor on Linux, the most simple way is to start (e.g) from an .svg version of the cursor, and to convert it into .xbm file including the .mask associated file, and using the name the cursor will have at the end, using The Gimp . You'll have to adjust the hotspot too, and to fix a bit the build, but once adjusted, you'll be able to do what you want.


For further information, the source files, for the eraser96, are ( the .xbm.h and the .xbm.mask) in vcl/unx/source/inc

  • vcl/unx/source/inc/eraser96_mask.h
  • vcl/unx/source/inc/eraser96_curs.h


Declare the new cursor in vcl/unx/source/inc/salcursors.h :

Index: vcl/unx/source/inc/salcursors.h
===================================================================
--- vcl/unx/source/inc/salcursors.h	(révision 523)
+++ vcl/unx/source/inc/salcursors.h	(copie de travail)
@@ -163,3 +163,6 @@
 #include "tblselsw_mask.h"
 #include "paintbrush_curs.h"
 #include "paintbrush_mask.h"
+#include "eraser96_curs.h"
+#include "eraser96_mask.h"
+


using gtk

The cursors are either gtk cursors (nice cursors), or the vcl cursors, but this needs to be mentionned. Below, we simply add our eraser, to see it in annotations mode (Impress).

Index: vcl/unx/gtk/app/gtkdata.cxx
===================================================================
--- vcl/unx/gtk/app/gtkdata.cxx (revision 634)
+++ vcl/unx/gtk/app/gtkdata.cxx (working copy)
@@ -443,7 +443,10 @@
             // --> FME 2004-08-16 #i20119# Paintbrush tool
             MAKE_CURSOR( POINTER_PAINTBRUSH, paintbrush_ );
             // <--
-
+#ifdef OOo4Kids
+           // ericb : was missing when gtk is enabled
+            MAKE_CURSOR( POINTER_ERASER, eraser96_ );
+#endif
                default:
                        fprintf( stderr, "pointer %d not implemented", ePointerStyle );
                        break;

Unit test: verified working on Linux PowerPC.

other cases

TO BE CONTINUED : add an example of the use of POINTER_ERASER in Impress, in the next step for the new canvas in progress.


Known issues : mostly Windows where the cursor's size is naturaly limited to 32 x 32, at least with Windows XP (minimal required version)

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox