RISCOS.com

www.riscos.com Technical Support:
Programmer's Reference Manual

 

Drag An Object


Introduction and Overview

In RISC OS 3.6 the DragAnObject module was introduced. It provides SWI calls similar to those provided by the DragASprite module, save that you can use them to make the pointer drag any object around the screen. To do so, you must specify a SWI or a C / assembler function to render the object.

Since not all users will prefer this effect to dragging an outline - whether for aesthetics or performance - there is a bit in the CMOS RAM used to indicate their preference. (See CMOS RAM allocation.) You should examine that bit before using this module; if it shows that the user would prefer to drag outlines, oblige them!

To drag an object:

  1. Find or create a SWI or a C / assembler function to render the object to the screen. For example, you might use the SWI DrawFile_Render to render a Draw file.
  2. Set up any registers / parameters you need to pass to the SWI / function; and any workspace they may point to, including - if necessary - the object itself.
  3. Call the SWI DragAnObject_Start. This renders your object into its own workspace - so you can dispose of any workspace required by the rendering SWI / function whenever you like - and then starts a Wimp drag.
  4. When the Wimp sends you an indication that your drag has finished, you should call the SWI DragAnObject_Stop.

SWI calls


DragAnObject_Start
(SWI &49C40)

Starts dragging an object

On entry

R0 = flags
R1 = renderer called to render the object:

SWI number (R0 bit 16 = 0 on entry), or pointer to C / assembler function
R2 = pointer to block holding registers / parameters to pass to SWI / function
R3 = pointer to 16-byte block containing box
R4 = pointer to optional 16-byte block containing bounding box (see flags)
On exit

R0 - R4 preserved

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call starts dragging an object. To do so, it uses the given SWI / function to render your object twice into workspace that it claims. It then combines the two images into a single masked image, so only those pixels rendered will be used for the drag. It finally starts a Wimp drag of the masked image, and frees any workspace not needed for the drag itself.

You may dispose of any workspace used by the rendering SWI / function as soon as this call returns. If there is insufficient memory available to start the drag, the call reverts to a normal drag of a dotted outline.

The flags given in R0 have the following meanings:

Bits Meaning
0 - 1 Horizontal location of object in box:
00 left
01 centre
10 right
2 - 3 Vertical location of object in box:
00 bottom
01 centre
10 top
4 - 5 Drag bounding box is:
00 whole screen
01 display area of window that the pointer's over
10 specified in block pointed to by R4
6 Bounding box applies to:
0 the box
1 the pointer
7 Control of drop-shadow:
0 don't do a drop-shadow
1 make a drop shadow
8 Control of dithering:
0 dither the dragged object
1 don't dither the dragged object
9 - 15 Reserved for future use - should be set to 0
16 Rendering is done by:
0 a SWI (see below)
1 a C / assembler function (see below)
17 If the renderer is a function, it is called in:
0 User mode
1 SVC mode (use for modules; also allows access to statics)
18 - 31 Reserved for future use - should be set to 0

The type of renderer is set by bit 16 of the flags:

  • If the bit is clear then the renderer is a SWI. The block pointed to by R2 should be ten words long. These ten words are loaded into R0 - R9, and the SWI is then called from SVC mode.
  • If the bit is set then the renderer is a C / assembler function, which is called in an APCS-conformant manner. The block pointed to by R2 should be four words long; these are loaded into R0 - R3 (known as a1 - a4 in the APCS) and passed as parameters to the function. R10 is set to the stack limit for a full descending stack (known as sl in the APCS), R13 is the stack pointer (known as sp in the APCS), and R14 is the link register (known as lr in the APCS).

The blocks pointed to by R3 and - optionally - R4 have the following format:

Offset Use
0 x-low box
4 y-low bottom-left (x-low, y-low) is inclusive
8 x-high top-right (x-high, y-high) is exclusive
12 y-high
Related SWIs

DragASprite_Start, DragAnObject_Stop

Related vectors

None


DragAnObject_Stop
(SWI &49C41)

Terminates any current drag operation, and releases workspace

On entry

--

On exit

--

Interrupts

Interrupt status is undefined
Fast interrupts are enabled

Processor mode

Processor is in SVC mode

Re-entrancy

Not defined

Use

This call terminates any current drag operation, and releases any workspace still claimed to do a drag. You should make this call when your application receives the User_Drag_Box reason code from Wimp_Poll (see Wimp_Poll) during a drag.

Related SWIs

DragAnObject_Start

Related vectors

None

Example programs

The following code fragments show how you might call DragAnObject_Start from C:

SWI renderer

void start_drag(...)
{
  _kernel_swi_regs regs, render;
  /* Set up registers for Wimp_PlotIcon renderer */
  render.r[1] = (int) &icon;
  render.r[4] = 0;
  render.r[5] = 0;
  /* Set up registers for DragAnObject_Start... */
  regs.r[0] = some flags;
  regs.r[1] = Wimp_PlotIcon;
  regs.r[2] = (int) &render;
  regs.r[3] = (int) &bbox;
  /* ...and call it */
  _kernel_swi(DragAnObject_Start, &regs, &regs);
}

Code renderer

void _my_render(data)
{
  /* do the render */
}
void start_drag(...)
{
  _kernel_swi_regs regs;
  int              render[4];
  /* Set up registers for _my_render renderer; render[0] - render[3] */
  /* will be passed to the function as parameters */
  render[0] = (int) data;       /* as required by renderer */
  /* Set up registers for DragAnObject_Start... */
  /* (tell it we're a function and a module) */
  regs.r[0] = some_flags + (1<<16) + (1<<17);
  regs.r[1] = (int) _my_render;
  regs.r[2] = (int) &render;
  regs.r[3] = (int) &bbox;
  /* ...and call it */
  _kernel_swi(DragAnObject_Start, &regs, &regs);
}

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015