home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 2
/
AUCD2.iso
/
program
/
vista.arc
/
c
/
window
< prev
next >
Wrap
Text File
|
1996-02-01
|
25KB
|
1,083 lines
// **************************************************************************
// Copyright 1996 David Allison
//
// VV VV IIIIII SSSSS TTTTTT AA
// VV VV II SS TT AA AA
// VV VV II SSSS TT AA AA
// VV VV II SS TT AAAAAAAA
// VV IIIIII SSSS TT AA AA
//
// MULTI-THREADED C++ WIMP CLASS LIBRARY
// for RISC OS
// **************************************************************************
//
// P U B L I C D O M A I N L I C E N C E
// -------------------------------------------
//
// This library is copyright. You may not sell the library for
// profit, but you may sell products which use it providing
// those products are presented as executable code and are not
// libraries themselves. The library is supplied without any
// warranty and the copyright owner cannot be held responsible for
// damage resulting from failure of any part of this library.
//
// See the User Manual for details of the licence.
//
// *************************************************************************
//
// c.window
//
#include "Vista:task.h"
#include "Vista:window.h"
#include <swis.h>
#include <kernel.h>
#include <stdarg.h>
#include <stdio.h>
Window::Window (Task *tsk, char *tname, char *m)
{
void *defn ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
int block[9] ;
task = tsk ;
//t->print ("creating window, tsk = %x, name = %s\n",tsk,tname) ;
if ((defn = tsk->find_template (tname)) == NULL)
throw ("No such Template") ;
r.r[1] = (int)defn ;
if ((e = _kernel_swi (Wimp_CreateWindow, &r, &r)) != NULL)
throw (e) ;
handle = r.r[0] ;
template_data = defn ;
block[0] = handle ;
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_GetWindowState, &r, &r)) != NULL)
throw (e) ;
x0 = block[1] ;
y0 = block[2] ;
x1 = block[3] ;
y1 = block[4] ;
scx = block[5] ;
scy = block[6] ;
prev = NULL ;
next = NULL ;
//::print ("window handle = %x",handle) ;
tsk->add_window(this) ; // add the window to the task
is_open = FALSE ;
icons = NULL ;
last_icon = NULL ;
objects = NULL ;
last_object = NULL ;
if (m == NULL)
default_menu = NULL ;
else
{
default_menu = tsk->find_menu (m) ;
if (default_menu == NULL)
throw ("Unknown menu") ;
}
sub_windows = NULL ; // no subwindows
parent = NULL ; // no parent
tracker = NULL ;
deleting = false ;
}
Window::Window (Window *w, char *tname, int anchor, char *m)
{
void *defn ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
int block[9] ;
// ::print ("creating sub window, name = %s\n",tname) ;
this->anchor = anchor ;
task = w->task ;
if ((defn = task->find_template (tname)) == NULL)
throw ("No such Template") ;
r.r[1] = (int)defn ;
if ((e = _kernel_swi (Wimp_CreateWindow, &r, &r)) != NULL)
throw (e) ;
handle = r.r[0] ;
template_data = defn ;
block[0] = handle ;
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_GetWindowState, &r, &r)) != NULL)
throw (e) ;
// if the window is anchored then the coords are relative to the top of the parent
// window, otherwise they are relative to the bottom
switch (anchor)
{
case A_NONE:
case A_BOTTOM:
x0 = block[1] - w->x0 ;
y0 = block[2] - w->y0 ;
x1 = block[3] - w->x0 ;
y1 = block[4] - w->y0 ;
break ;
case A_LEFT:
case A_TOP:
x0 = block[1] - w->x0 ;
y0 = block[2] - w->y1 ;
x1 = block[3] - w->x0 ;
y1 = block[4] - w->y1 ;
break ;
case A_RIGHT:
x0 = block[1] - w->x1 ;
y0 = block[2] - w->y1 ;
x1 = block[3] - w->x1 ;
y1 = block[4] - w->y1 ;
break ;
}
scx = block[5] ;
scy = block[6] ;
//::print ("window handle = %x",handle) ;
prev = NULL ;
next = NULL ;
w->add_sub_window(this) ; // add the window to the task
is_open = FALSE ;
icons = NULL ;
last_icon = NULL ;
objects = NULL ;
last_object = NULL ;
if (m == NULL)
default_menu = NULL ;
else
{
default_menu = task->find_menu (m) ;
if (default_menu == NULL)
throw ("Unknown menu") ;
}
sub_windows = NULL ; // no subwindows
tracker = NULL ;
deleting = false ;
}
Window::~Window()
{
Icon *ni ;
Window *nw ;
Object *no ;
deleting = true ;
if (is_open)
do_close() ;
for (Icon *i = icons ; i != NULL ; i = ni)
{
ni = i->next ;
delete i ;
}
for (Window *w = sub_windows ; w != NULL ; w = nw)
{
nw = w->next ;
delete w ;
}
for (Object *o = objects ; o != NULL ; o = no)
{
no = o->next ;
delete o ;
}
task->remove_window (this) ;
if (parent != NULL)
parent->remove_sub_window (this) ;
if (tracker != NULL)
delete tracker ;
task->free_template(template_data) ; // free up the definition data
}
//
// get a sub window's x0 coordinate in screen coordinates
//
int Window::subx0(Window *sub)
{
int myx0 ; // my x0 coord
if (parent != NULL)
myx0 = parent->subx0(this) ;
else
myx0 = x0 ;
switch (sub->anchor)
{
case A_NONE:
case A_BOTTOM:
default:
return myx0 + sub->x0 ;
case A_LEFT:
case A_TOP:
return myx0 + sub->x0 ;
case A_RIGHT:
return myx0 + (x1-x0) + sub->x0 ; // == myx1 + sub->x0
}
}
//
// get the y1 coordinate for a sub window in screen coordinates
//
int Window::suby1(Window *sub)
{
int myy1 ; // my y1 coord
if (parent != NULL)
myy1 = parent->suby1(this) ;
else
myy1 = y1 ;
switch (sub->anchor)
{
case A_NONE:
case A_BOTTOM:
default:
return myy1 - (y1-y0) + sub->y1 ; // == myy0 + sub->y1
case A_LEFT:
case A_TOP:
return myy1 + sub->y1 ;
case A_RIGHT:
return myy1 + sub->y1 ;
}
}
void Window::add_icon(Icon *i)
{
i->next = NULL ;
if (icons == NULL)
icons = last_icon = i ;
else
{
last_icon->next = i ;
i->prev = last_icon ;
last_icon = i ;
}
}
void Window::remove_icon (Icon *i)
{
if (i->prev == NULL)
icons = i->next ;
else
i->prev->next = i->next ;
if (i->next == NULL)
last_icon = i->prev ;
else
i->next->prev = i->prev ;
}
void Window::add_object(Object *o)
{
Object *obj = objects ;
while (obj != NULL && obj->priority < o->priority) // find position
obj = obj->next ;
o->next = obj ;
if (obj == NULL) // at end of queue
o->prev = last_object ;
else
o->prev = obj->prev ;
if (o->prev == NULL)
objects = o ;
else
o->prev->next = o ;
if (o->next == NULL)
last_object = o ;
else
o->next->prev = o ;
}
void Window::remove_object (Object *o)
{
if (o->prev == NULL)
objects = o->next ;
else
o->prev->next = o->next ;
if (o->next == NULL)
last_object = o->prev ;
else
o->next->prev = o->prev ;
}
void Window::add_sub_window (Window *w)
{
if (sub_windows == NULL)
sub_windows = last_sub_window = w ;
else
{
last_sub_window->next = w ;
w->prev = last_sub_window ;
last_sub_window = w ;
}
w->parent = this ;
}
void Window::remove_sub_window (Window *w)
{
if (w->prev == NULL)
sub_windows = w->next ;
else
w->prev->next = w->next ;
if (w->next == NULL)
last_sub_window = w->prev ;
else
w->next->prev = w->prev ;
w->parent = NULL ;
}
void Window::do_open(int x0, int y0, int x1, int y1, int scx, int scy, int behind)
{
int block[8] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
if (parent == NULL) // top window? - set coords
{
this->x0 = x0 ;
this->y0 = y0 ;
this->x1 = x1 ;
this->y1 = y1 ;
}
this->scx = scx ; // set scroll positions
this->scy = scy ;
for (Window *w = sub_windows ; w != NULL ; w = w->next)
w->do_open(behind) ;
block[0] = handle ;
block[1] = x0 ;
block[2] = y0 ;
block[3] = x1 ;
block[4] = y1 ;
block[5] = scx ;
block[6] = scy ;
if (sub_windows != NULL)
block[7] = sub_windows->handle ; // open behind first subwindow
else
block[7] = behind ;
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_OpenWindow, &r, &r)) != NULL)
throw (e) ;
is_open = TRUE ;
}
void Window::do_open(int behind)
{
int block[9] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
block[0] = handle ;
for (Window *w = sub_windows ; w != NULL ; w = w->next)
w->do_open(behind) ;
if (parent == NULL) // top window
{
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_GetWindowState, &r, &r)) != NULL)
throw (e) ;
}
else
{ // sub window
switch (anchor)
{
case A_NONE:
block[1] = parent->x0 + x0 - parent->scx ;
block[2] = parent->y0 + y0 - parent->scy ;
block[3] = parent->x0 + x1 - parent->scx ;
block[4] = parent->y0 + y1 - parent->scy ;
break ;
case A_LEFT:
case A_TOP:
block[1] = parent->x0 + x0 ;
block[2] = parent->y1 + y0 ;
block[3] = parent->x0 + x1 ;
block[4] = parent->y1 + y1 ;
break ;
case A_RIGHT:
block[1] = parent->x1 + x0 ;
block[2] = parent->y1 + y0 ;
block[3] = parent->x1 + x1 ;
block[4] = parent->y1 + y1 ;
break ;
case A_BOTTOM:
block[1] = parent->x0 + x0 ;
block[2] = parent->y0 + y0 ;
block[3] = parent->x0 + x1 ;
block[4] = parent->y0 + y1 ;
break ;
}
block[5] = scx ;
block[6] = scy ;
}
if (sub_windows != NULL)
block[7] = sub_windows->handle ; // open behind first subwindow
else
block[7] = behind ; // open behind that given
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_OpenWindow, &r, &r)) != NULL)
throw (e) ;
is_open = TRUE ;
}
void Window::do_open(int x0, int y0, int behind)
{
int block[8] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
int xdiff, ydiff ;
r.r[1] = (int)block ;
block[0] = handle ;
if ((e = _kernel_swi (Wimp_GetWindowState, &r, &r)) != NULL)
throw (e) ;
xdiff = block[3] - block[1] ;
ydiff = block[4] - block[2] ;
this->x0 = x0 ;
this->y0 = y0 ;
this->x1 = x0 + xdiff ;
this->y1 = y0 + ydiff ;
this->scx = block[5] ; // set scroll positions
this->scy = block[6] ;
block[1] = this->x0 ;
block[2] = this->y0 ;
block[3] = this->x1 ;
block[4] = this->y1 ;
for (Window *w = sub_windows ; w != NULL ; w = w->next)
w->do_open(behind) ;
if (sub_windows != NULL)
block[7] = sub_windows->handle ; // open behind first subwindow
else
block[7] = behind ;
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_OpenWindow, &r, &r)) != NULL)
throw (e) ;
is_open = TRUE ;
}
void Window::do_close()
{
int block ; ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
for (Window *w = sub_windows ; w != NULL ; w = w->next)
w->do_close() ;
block = handle ;
r.r[1] = (int)&block ;
if ((e = _kernel_swi (Wimp_CloseWindow, &r, &r)) != NULL)
throw (e) ;
is_open = FALSE ;
}
//
// redraw part of a window
//
void Window::do_redraw(int x0, int y0, int x1, int y1)
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[0] = handle ;
r.r[1] = x0 ;
r.r[2] = y0 ;
r.r[3] = x1 ;
r.r[4] = y1 ;
if ((e = _kernel_swi (Wimp_ForceRedraw, &r, &r)) != NULL)
throw (e) ;
}
//
// redraw all of a window
//
void Window::do_redraw()
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
int block[30] ;
block[0] = handle ;
r.r[1] = ((int)block) | 1 ; // dont read icons
if ((e = _kernel_swi (Wimp_GetWindowInfo, &r, &r)) != NULL)
throw (e) ;
r.r[0] = handle ;
r.r[1] = block[11] ;
r.r[2] = block[12] ;
r.r[3] = block[13] ;
r.r[4] = block[14] ;
if ((e = _kernel_swi (Wimp_ForceRedraw, &r, &r)) != NULL)
throw (e) ;
}
//
// update a rectangle of the window given its window coords
//
void Window::do_update(int x0, int y0, int x1, int y1)
{
int block[11] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
Object *object ;
r.r[1] = (int)block ;
block[0] = handle ;
task->enter_critical() ;
if ((e = _kernel_swi (Wimp_UpdateWindow, &r, &r)) != NULL)
{
task->exit_critical() ;
throw (e) ;
}
while (r.r[0] != 0)
{
for (object = objects ; object != NULL ; object = object->next)
object->update(block[1], block[2], block[3], block[4]) ;
if ((e = _kernel_swi (Wimp_GetRectangle, &r, &r)) != NULL)
{
task->exit_critical() ;
throw (e) ;
}
}
task->exit_critical() ;
}
//
// update the whole window
//
void Window::do_update()
{
Info *inf = info() ;
int width, height ;
width = inf->box.x1 - inf->box.x0 ;
height = inf->box.y1 - inf->box.y0 ;
do_update (0, -height, width, 0) ;
}
void Window::do_drag (int type, int x0, int y0, int x1, int y1,
int px0, int py0, int px1, int py1)
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
int block[40] ;
block[0] = handle ;
block[1] = type ;
block[2] = x0 ;
block[3] = y0 ;
block[4] = x1 ;
block[5] = y1 ;
if (px0 == -1)
{
block[6] = 0 ;
block[7] = 0 ;
block[8] = 30000 ;
block[9] = 30000 ;
}
else
{
block[6] = px0 ;
block[7] = py0 ;
block[8] = px1 ;
block[9] = py1 ;
}
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_DragBox, &r, &r)) != NULL)
throw (e) ;
}
void Window::do_drag (char *sprite)
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
int block[5] ;
int x, y ;
r.r[1] = (int)block ;
_kernel_swi (Wimp_GetPointerInfo, &r, &r) ; // read pointer position
x = block[0] ;
y = block[1] ;
r.r[0] = 0xc5 ;
r.r[1] = 1 ;
r.r[2] = (int)sprite ;
r.r[3] = (int)block ;
block[0] = x - 100 ;
block[1] = y - 100 ;
block[2] = x + 100 ;
block[3] = y + 100 ;
if ((e = _kernel_swi (DragASprite_Start, &r, &r)) != NULL)
throw (e) ;
}
void Window::do_drag (char *sprite, int x0, int y0, int x1, int y1, int flags,
int px0, int py0,
int px1, int py1)
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
int block1[4] ;
int block2[4] ;
int x, y ;
r.r[0] = flags ;
r.r[1] = 1 ;
r.r[2] = (int)sprite ;
r.r[3] = (int)block1 ;
r.r[4] = (int)block2 ;
block1[0] = x0 ;
block1[1] = y0 ;
block1[2] = x1 ;
block1[3] = y1 ;
block2[0] = px0 ;
block2[1] = py0 ;
block2[2] = px1 ;
block2[3] = py1 ;
if ((e = _kernel_swi (DragASprite_Start, &r, &r)) != NULL)
throw (e) ;
}
Window::State *Window::state()
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
wstate.handle = handle ;
r.r[1] = (int)&wstate ;
if ((e = _kernel_swi (Wimp_GetWindowState, &r, &r)) != NULL)
throw (e) ;
return &wstate ;
}
Window::Info *Window::info()
{
winfo.handle = handle ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[1] = ((int)&winfo) | 1 ; // no icons
if ((e = _kernel_swi (Wimp_GetWindowInfo, &r, &r)) != NULL)
throw (e) ;
return &winfo ;
}
void Window::set_extent(int x0, int y0, int x1, int y1)
{
int block[4] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[0] = handle ;
r.r[1] = (int)block ;
block[0] = x0 ;
block[1] = y0 ;
block[2] = x1 ;
block[3] = y1 ;
if ((e = _kernel_swi (Wimp_SetExtent, &r, &r)) != NULL)
throw (e) ;
}
void Window::set_extent(int width, int height)
{
Info *inf = info() ;
int block[4] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[0] = handle ;
r.r[1] = (int)block ;
block[0] = inf->extent.x0 ;
block[1] = inf->extent.y1 - height ;
block[2] = inf->extent.x0 + width ;
block[3] = inf->extent.y1 ;
if ((e = _kernel_swi (Wimp_SetExtent, &r, &r)) != NULL)
throw (e) ;
}
void Window::set_width(int x0, int x1)
{
Info *inf = info() ;
int block[4] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[0] = handle ;
r.r[1] = (int)block ;
block[0] = x0 ;
block[1] = inf->extent.y0 ;
block[2] = x1 ;
block[3] = inf->extent.y1 ;
if ((e = _kernel_swi (Wimp_SetExtent, &r, &r)) != NULL)
throw (e) ;
}
void Window::set_height(int y0, int y1)
{
Info *inf = info() ;
int block[4] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[0] = handle ;
r.r[1] = (int)block ;
block[0] = inf->extent.x0 ;
block[1] = y0 ;
block[2] = inf->extent.x1 ;
block[3] = y1 ;
if ((e = _kernel_swi (Wimp_SetExtent, &r, &r)) != NULL)
throw (e) ;
}
void Window::set_width(int width)
{
Info *inf = info() ;
int block[4] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[0] = handle ;
r.r[1] = (int)block ;
block[0] = inf->extent.x0 ;
block[1] = inf->extent.y0 ;
block[2] = inf->extent.x0 + width ;
block[3] = inf->extent.y1 ;
if ((e = _kernel_swi (Wimp_SetExtent, &r, &r)) != NULL)
throw (e) ;
}
void Window::set_height(int height)
{
Info *inf = info() ;
int block[4] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[0] = handle ;
r.r[1] = (int)block ;
block[0] = inf->extent.x0 ;
block[1] = inf->extent.y1 - height ;
block[2] = inf->extent.x1 ;
block[3] = inf->extent.y1 ;
if ((e = _kernel_swi (Wimp_SetExtent, &r, &r)) != NULL)
throw (e) ;
}
void Window::get_outline(int &x0, int &y0, int &x1, int &y1)
{
int block[5] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
r.r[1] = (int)block ;
block[0] = handle ;
if ((e = _kernel_swi (Wimp_GetWindowOutline, &r, &r)) != NULL)
throw (e) ;
x0 = block[1] ;
y0 = block[2] ;
x1 = block[3] ;
y1 = block[4] ;
}
void Window::read_position()
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
int block[9] ;
block[0] = handle ;
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_GetWindowState, &r, &r)) != NULL)
throw (e) ;
x0 = block[1] ;
y0 = block[2] ;
x1 = block[3] ;
y1 = block[4] ;
scx = block[5] ;
scy = block[6] ;
}
void Window::set_title (char *format ...)
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
Info *inf = info() ;
va_list ap ;
va_start (ap, format) ;
// ::print ("info = %x\n",&inf) ;
// ::print ("printing to %x",inf.title.indirecttext.buffer) ;
vsprintf (inf->title.indirecttext.buffer, format, ap) ;
r.r[0] = -1 ;
r.r[1] = inf->box.x0 ;
r.r[2] = inf->box.y1 ;
r.r[3] = inf->box.x1 ;
r.r[4] = inf->box.y1 + 36 ;
if ((e = _kernel_swi (Wimp_ForceRedraw, &r, &r)) != NULL)
throw (e) ;
}
char *Window::title ()
{
Info *inf = info() ;
return inf->title.indirecttext.buffer ;
}
void Window::redraw()
{
int block[11] ;
_kernel_swi_regs r ;
_kernel_oserror *e ;
Object *object ;
int wx0, wy0, wx1, wy1 ; // work area coords
int scx, scy ;
int gx0, gy0, gx1, gy1 ;
int minx, maxy ;
r.r[1] = (int)block ;
block[0] = handle ;
task->enter_critical() ;
if ((e = _kernel_swi (Wimp_RedrawWindow, &r, &r)) != NULL)
{
task->exit_critical() ;
throw (e) ;
}
if (r.r[0] != 0)
{
if (parent != NULL)
{
x0 = block[1] - parent->x0 ;
y0 = block[2] - parent->y0 ;
x1 = block[3] - parent->x0 ;
y1 = block[4] - parent->y0 ;
}
else
{
x0 = block[1] ;
y0 = block[2] ;
x1 = block[3] ;
y1 = block[4] ;
}
this->scx = block[5] ;
this->scy = block[6] ;
}
while (r.r[0] != 0)
{
scx = block[5] ;
scy = block[6] ;
gx0 = block[7] ;
gy0 = block[8] ;
gx1 = block[9] ;
gy1 = block[10] ;
minx = block[1] ;
maxy = block[4] ;
wx0 = gx0 + (scx - minx) ;
wy0 = gy0 + (scy - maxy) ;
wx1 = gx1 + (scx - minx) ;
wy1 = gy1 + (scy - maxy) ;
for (object = objects ; object != NULL ; object = object->next)
object->redraw(wx0, wy0, wx1, wy1) ;
if ((e = _kernel_swi (Wimp_GetRectangle, &r, &r)) != NULL)
{
task->exit_critical() ;
throw (e) ;
}
}
task->exit_critical() ;
}
void Window::open(int x0, int y0, int x1, int y1, int scx, int scy, int behind)
{
do_open (x0, y0, x1, y1, scx, scy, behind) ;
}
void Window::close()
{
do_close() ;
}
void Window::drag (int x0, int y0, int x1, int y1, int id)
{
}
void Window::pointer(int entering)
{
if (objects == NULL) // no objects?
return ;
if (entering)
{
if (tracker == NULL)
{
tracker = new MouseTracker (this) ;
tracker->start() ;
}
}
else
{
if (tracker != NULL)
{
delete tracker ;
tracker = NULL ;
}
}
}
Object *Window::find_object (int mx, int my)
{
Object *object ;
for (object = last_object ; object != NULL ; object = object->prev)
if (object->compare(mx, my))
return object ;
return NULL ;
}
Object *Window::find_object (char *name)
{
Object *object ;
for (object = last_object ; object != NULL ; object = object->prev)
if (strcmp (name, object->name) == 0)
return object ;
return NULL ;
}
void Window::click(int mx, int my, int buttons, int icon)
{
}
void Window::key(int icon, int x, int y, int height, int index, int code)
{
}
void Window::scroll(int x0, int y0, int x1, int y1, int scx, int scy, int behind, int xdir, int ydir)
{
}
void Window::caret(int gaining, int icon, int x, int y, int height, int index)
{
}
//
// display a menu on the screen due to the menu button being pressed over the window
//
Menu *Window::display_menu(int x, int y, int button, int icon)
{
if (default_menu == NULL)
{
char *menu_name = get_menu(x, y, button, icon) ;
if (menu_name == NULL)
return NULL ;
Menu *m = task->find_menu (menu_name) ;
if (m != NULL)
{
m->open (x - 40, y) ;
return m ;
}
return NULL ; // no menu
}
else
{
pre_menu (default_menu, x, y, button, icon) ;
default_menu->open (x - 40, y) ;
return default_menu ;
}
}
//
// give user a chance to change the menu before display
//
void Window::pre_menu (Menu *m, int x, int y, int button, int icon)
{
}
//
// this window doesn't have a default menu, ask the user to provide one
//
char *Window::get_menu (int x, int y, int button, int icon)
{
return NULL ;
}
void Window::menu (MenuItem items[])
{
}
Icon *Window::find_icon (int icon)
{
Icon *ip ;
for (ip = icons ; ip != NULL ; ip = ip->next)
if (ip->compare(icon))
break ;
return ip ;
}
Window *Window::find_window (int h)
{
Window *sub ;
if (h == handle)
return this ;
for (Window *w = sub_windows ; w != NULL ; w = w->next)
if ((sub = w->find_window(h)) != NULL)
return sub ;
return NULL ;
}
void Window::mode_change()
{
Object *object ;
for (object = objects ; object != NULL ; object = object->next)
object->mode_change() ;
}
char *Window::help (int mx, int my, int buttons, int icon)
{
return NULL ;
}
//
// mouse tracker thread
//
MouseTracker::MouseTracker (Window *w)
: Thread ("Tracker", 55)
{
window = w ;
}
MouseTracker::~MouseTracker()
{
}
void MouseTracker::run()
{
_kernel_swi_regs r ;
_kernel_oserror *e ;
int block[5] ;
Object *object = NULL ; // current object
Object *o ;
// Window *w = new Window (window->task, "counter") ;
// Icon *ic = new Icon (w, 0) ;
// w->do_open() ;
for (;;)
{
r.r[1] = (int)block ;
if ((e = _kernel_swi (Wimp_GetPointerInfo, &r, &r)) != NULL) // get pointer position
throw (e) ;
o = window->find_object(block[0], block[1]) ; // look for an object
// ic->print ("%x",o) ;
if (o != object) // has object changed?
{
if (object != NULL) // was there a previous object
object->pointer(0) ; // yes, leave
object = o ; // this is now current object
if (o != NULL) // any object now
o->pointer (1) ; // enter it
}
yield() ; // yield to next thread
}
}