/* Copyright 1997 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /***************************************************/ /* File : Mouse.c */ /* */ /* Purpose: Mouse pointer related functions for */ /* the browser. */ /* */ /* Author : A.D.Hodgkinson */ /* */ /* History: 14-Mar-97: Created. */ /***************************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "swis.h" #include "kernel.h" #include "HTMLLib.h" /* HTML library API, Which will include html2_ext.h, tags.h and struct.h */ #include "wimp.h" #include "wimplib.h" #include "event.h" #include "toolbox.h" #include "svcprint.h" #include "Global.h" #include "Utils.h" #include "Handlers.h" #include "Mouse.h" /* Locals */ static int mouse_watch = 0; static int mouse_x; static int mouse_y; static int mouse_time; static int mouse_on = 1; static int mouse_shape = 1; static int mouse_used = 0; /*************************************************/ /* mouse_watch_pointer_control() */ /* */ /* Controls watching movement of the mouse */ /* pointer; if turned on, when the pointer moves */ /* the function will ensure that the pointer is */ /* also visible. */ /* */ /* Parameters: 1 to turn watching on, 0 to turn */ /* it off. */ /*************************************************/ void mouse_watch_pointer_control(int on) { if (on) { if (!mouse_watch) { mouse_x = mouse_y = mouse_time = -1; register_null_claimant(Wimp_ENull, mouse_watch_pointer, NULL); mouse_watch = 1; } } else { if (mouse_watch) { deregister_null_claimant(Wimp_ENull, mouse_watch_pointer, NULL); mouse_watch = 0; } } } /*************************************************/ /* mouse_watch_pointer() */ /* */ /* Watches to see if the mouse pointer moves, */ /* and if so, ensures the pointer is visible. */ /* */ /* Parameters are as standard for a Wimp event */ /* handler. */ /*************************************************/ int mouse_watch_pointer(int eventcode, WimpPollBlock * block, IdBlock * idb, void * handle) { WimpGetPointerInfoBlock i; if (!wimp_get_pointer_info(&i)) { if (mouse_x < 0) mouse_x = i.x; if (mouse_y < 0) mouse_y = i.y; if (mouse_time < 0) _swix(OS_ReadMonotonicTime, _OUT(0), &mouse_time); if (mouse_x != i.x || mouse_y != i.y) { if (!mouse_on) mouse_pointer_on(); mouse_x = mouse_y = mouse_time = -1; mouse_used = 1; } else if (mouse_on) { int t; _swix(OS_ReadMonotonicTime, _OUT(0), &t); if (t - mouse_time > 500) mouse_pointer_off(); } } return 0; } /*************************************************/ /* mouse_pointer_on() */ /* */ /* Turns the mouse pointer on immediately. */ /*************************************************/ void mouse_pointer_on(void) { if (!mouse_on) { mouse_x = mouse_y = mouse_time = -1; mouse_on = 1; mouse_set_pointer_shape(mouse_shape); } } /*************************************************/ /* mouse_pointer_off() */ /* */ /* Turns the mouse pointer off immediately. */ /*************************************************/ void mouse_pointer_off(void) { if (mouse_on && !mouse_used) { mouse_x = mouse_y = mouse_time = -1; mouse_set_pointer_shape(Mouse_Shape_Off); mouse_on = 0; } } /*************************************************/ /* mouse_force_unused() */ /* */ /* Resets the internal mouse_used flag back to */ /* zero, so that the mouse pointer may be */ /* turned off (otherwise the user has moved the */ /* pointer and it shouldn't be switched off). */ /*************************************************/ void mouse_force_unused(void) { mouse_used = 0; } /*************************************************/ /* mouse_set_pointer_shape() */ /* */ /* Sets the shape of the pointer; shape 0 turns */ /* it off. If mouse_on is set to zero, this will */ /* *not* override that setting. */ /* */ /* Parameters: Pointer shape; see Mouse.h for */ /* definitions of shapes. */ /*************************************************/ void mouse_set_pointer_shape(int shape) { if (shape) mouse_shape = shape; /* If the mouse is turned off, don't turn it back on... */ if (shape && !mouse_on) return; /* Otherwise change to the required shape */ switch (shape) { case Mouse_Shape_Off: _swix(OS_CLI, _IN(0), "Pointer 0"); break; default: /* Catchall - use normal pointer, so no 'break' */ case Mouse_Shape_Normal: _swix(OS_CLI, _IN(0), "Pointer 1"); break; case Mouse_Shape_Link: _swix(OS_SpriteOp, _INR(0,7), 292, sprite_block, "ptr_link", 2, controls.ptrlnkactvx, controls.ptrlnkactvy, 0, 0); break; case Mouse_Shape_Map: _swix(OS_SpriteOp, _INR(0,7), 292, sprite_block, "ptr_map", 2, controls.ptrmapactvx, controls.ptrmapactvy, 0, 0); break; case Mouse_Shape_UD: _swix(OS_SpriteOp, _INR(0,7), 292, sprite_block, "ptr_ud", 2, controls.ptrudactvx, controls.ptrudactvy, 0, 0); break; case Mouse_Shape_LR: _swix(OS_SpriteOp, _INR(0,7), 292, sprite_block, "ptr_lr", 2, controls.ptrlractvx, controls.ptrlractvy, 0, 0); break; case Mouse_Shape_UDLR: _swix(OS_SpriteOp, _INR(0,7), 292, sprite_block, "ptr_udlr", 2, controls.ptrudlractvx, controls.ptrudlractvy, 0, 0); break; case Mouse_Shape_NoResize: _swix(OS_SpriteOp, _INR(0,7), 292, sprite_block, "ptr_noresize", 2, controls.ptrnoractvx, controls.ptrnoractvy, 0, 0); break; case Mouse_Shape_ToScroll: _swix(OS_SpriteOp, _INR(0,7), 292, sprite_block, "ptr_toscroll", 2, controls.ptrtosactvx, controls.ptrtosactvy, 0, 0); break; case Mouse_Shape_Scrolling: _swix(OS_SpriteOp, _INR(0,7), 292, sprite_block, "ptr_scroll", 2, controls.ptrscractvx, controls.ptrscractvy, 0, 0); break; } } /*************************************************/ /* mouse_pointer_is_on() */ /* */ /* States whether the pointer is on or off. */ /* */ /* Returns: 1 if the pointer is on, else 0. */ /*************************************************/ int mouse_pointer_is_on(void) { if (mouse_on) return 1; return 0; } /*************************************************/ /* mouse_to() */ /* */ /* Moves the mouse to a given screen coordinate. */ /* */ /* Parameters: X coordinate to move to; */ /* */ /* Y coordinate to move to; */ /* */ /* 1 to always move, else only move */ /* if mouse_used is zero (so it */ /* looks as if the user has not yet */ /* used or does not have a mouse). */ /*************************************************/ void mouse_to(int x, int y, int now) { char block[5]; if (!now && mouse_used) return; block[0] = 3; block[1] = x & 0xff; block[2] = x >> 8; block[3] = y & 0xff; block[4] = y >> 8; _swix(OS_Word, _INR(0, 1), 21, block); } /*************************************************/ /* mouse_rectangle() */ /* */ /* Constrains the mouse pointer to a given */ /* rectangle, or returns the last rectangle set */ /* with this function. */ /* */ /* Parameters: Pointer to a BBox, in which the */ /* new rectangle is held, or NULL to */ /* set no new rectangle; */ /* */ /* 1 to rectangle the pointer now, */ /* else only rectangle it if it is */ /* not flagged as being used. */ /* */ /* Returns: Pointer to a BBox, in which the */ /* previously set coordinates are */ /* stored if the BBox pointer given */ /* as a parameter is NULL (else the */ /* coordinates in the given BBox */ /* will be the same as the coords */ /* in the returned BBox). */ /*************************************************/ BBox * mouse_rectangle(BBox * rect, int now) { char block[9]; static BBox last_rect; if (!now && mouse_used) return &last_rect; if (rect) { block[0] = 1; block[1] = rect->xmin & 0xff; block[2] = rect->xmin >> 8; block[3] = rect->ymin & 0xff; block[4] = rect->ymin >> 8; block[5] = rect->xmax & 0xff; block[6] = rect->xmax >> 8; block[7] = rect->ymax & 0xff; block[8] = rect->ymax >> 8; _swix(OS_Word, _INR(0, 1), 21, block); } last_rect = *rect; return &last_rect; }