home *** CD-ROM | disk | FTP | other *** search
- // **************************************************************************
- // 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.
- //
- // *************************************************************************
-
- //
- // Example of a DialogueBox
- //
-
- #include "threads.h"
- #include <kernel.h>
- #include <swis.h>
- #include <string.h>
- #include <math.h>
-
- //
- // define the main program variable
- //
-
- Threads *threads ;
-
- // -------------------------
- // Tracker class constructor
- // -------------------------
-
-
- Tracker::Tracker (Task *task)
- : Window (task, "main"),
- Thread ("tracker")
- {
- _kernel_swi_regs r ;
- int block[5] ;
- coords_display = new Icon (this, POSITION) ;
- time_display = new Icon (this, TIME) ;
- select_button = new Icon (this, SELECT) ;
- menu_button = new Icon (this, MENU) ;
- adjust_button = new Icon (this, ADJUST) ;
- select_display = new Icon (this, SELSTAT) ;
- menu_display = new Icon (this, MENSTAT) ;
- adjust_display = new Icon (this, ADJSTAT) ;
- speed_display = new Icon (this, SPEED) ;
- dist_display = new Icon (this, DIST) ;
- window_display = new Icon (this, WINDOW) ;
- icon_display = new Icon (this, ICON) ;
- speedometer = new Meter (this, SPEEDOMETER_BACKGROUND, SPEEDOMETER_VALUE, 5000) ;
- r.r[1] = (int)block ;
- _kernel_swi (Wimp_GetPointerInfo, &r, &r) ;
- prev_x = block[0] ;
- prev_y = block[1] ;
- _kernel_swi (OS_ReadMonotonicTime, &r, &r) ;
- prev_time = r.r[0] ;
- running = false ;
- }
-
- //
- // Tracker destructor
- //
-
- Tracker::~Tracker()
- {
- delete coords_display ;
- delete time_display ;
- delete select_button ;
- delete menu_button ;
- delete adjust_button ;
- delete select_display ;
- delete menu_display ;
- delete adjust_display ;
- delete speed_display ;
- delete dist_display ;
- delete window_display ;
- delete icon_display ;
- }
-
-
- //
- // This is called when the user clicks in the window outside all Icons.
- //
- // Note that we have not created an Icon object for the ShowBox button
- // but just deal with the click on it here. We could have created
- // an Icon object for it, but it makes the thing more complicated.
- //
-
- void Tracker::click(int x, int y, int button, int icon)
- {
- if (button & 4 && icon == STOP) // select on Stop icon
- running = false ;
- }
-
- //
- // thread run function. This function enters a loop until the thread is stopped
- // by setting the variable 'running' to false. Vista takes care of
- // switching between threads and polling the OS. There can be any number
- // of these threads running. Click the iconbar icon a few times to
- // see it.
- //
- // The 'yield()' function is called on each iteration because it is unlikley that
- // the mouse has moved much in the time it takes to read its position again, so
- // we might as well give another thread a chance to run. This improves
- // performance because it stops threads hogging the processor when there is
- // nothing for them to do.
- //
-
- void Tracker::run()
- {
- _kernel_swi_regs r ;
- int block[5] ;
- int x, y ;
- int buttons ;
- int window ;
- int icon ;
- int xdist,ydist, dist ;
- int time_diff ;
- int speed ;
- int prev_buttons = 0 ;
- int distance = 0 ;
- int select = 0 ;
- int menu = 0 ;
- int adjust = 0 ;
- int time = 0 ;
- int prev_time_display = 0 ;
- running = true ;
- do_open() ; // open the window
- while (running)
- {
- r.r[1] =(int)block ;
- _kernel_swi (Wimp_GetPointerInfo, &r, &r) ; // read pointer position
- x = block[0] ;
- y = block[1] ;
- buttons = block[2] ;
- window = block[3] ;
- icon = block[4] ;
- _kernel_swi (OS_ReadMonotonicTime, &r, &r) ; // read current time
- xdist = x - prev_x ;
- ydist = y - prev_y ;
- time_diff = r.r[0] - prev_time ; // calculate time taken
- time += time_diff ;
- if (buttons == prev_buttons && xdist == 0 && ydist == 0) // has mouse changed?
- {
- if (speed != 0)
- speed_display->write (0) ; // no, so don't change anything
- speed = 0 ;
- }
- else
- {
- dist = sqrt ((xdist * xdist) + (ydist * ydist)) ; // calculate distance moved
- distance += dist ;
- if (time_diff == 0)
- speed = 0 ;
- else
- speed = (dist * 100) / time_diff ; // OS units per second
- coords_display->print ("(%d,%d)",x,y) ; // display mouse position
- if (buttons & 4)
- {
- select++ ;
- select_button->select() ;
- }
- else
- select_button->unselect() ;
- if (buttons & 2)
- {
- menu++ ;
- menu_button->select() ;
- }
- else
- menu_button->unselect() ;
- if (buttons & 1)
- {
- adjust++ ;
- adjust_button->select() ;
- }
- else
- adjust_button->unselect() ;
- select_display->write (select) ;
- menu_display->write (menu) ;
- adjust_display->write (adjust) ;
- speed_display->write (speed) ;
- dist_display->write (distance) ;
- speedometer->write (speed) ;
- window_display->print ("%x",window) ;
- icon_display->write (icon) ;
- }
- if ((time / 100) > prev_time_display)
- {
- int secs = time / 100 ;
- int mins = secs / 60 ;
- time_display->print ("%d:%02d", mins, secs % 60) ; // display time in mins and secs
- }
- prev_time_display = time / 100 ;
- prev_buttons = buttons ; // store current state
- prev_time = r.r[0] ;
- prev_x = x ;
- prev_y = y ;
- yield() ; // give another thread a chance - improves performance
- }
- }
-
-
- // ************************************************************************
- // The main task class itself
- // ************************************************************************
-
-
- Threads::Threads()
- : Task ("Threads Example", "Threads", "!Threads", "iconbar")
- {
- }
-
- //
- // icon bar click on our icon
- //
-
- void Threads::click (int x, int y, int button, int icon)
- {
- Tracker tracker(this) ; // create a tracker
- tracker.start() ; // start it running
- sleep (&tracker) ; // sleep until thread terminates
- }
-
- //
- // menu hit on the iconbar menu
- //
-
-
- void Threads::menu(MenuItem items[])
- {
- switch (items[0])
- {
- case INFO:
- { // need these braces
- ProgramInfo proginfo (this, 4, "1.0 (9 Jan 1996)") ;
- proginfo.show() ;
- sleep (&proginfo) ;
- break ;
- }
- case QUIT:
- exit() ; // exit task (Task::exit())
- break ;
- }
- }
-
-
- main()
- {
- #ifdef __EASY_C
- try
- #endif
- {
- threads = new Threads() ; // create the task
- threads->run() ; // run it
- }
- #ifdef __EASY_C
- catch (_kernel_oserror *e)
- {
- _kernel_swi_regs r ;
- r.r[0] = (int)e ;
- r.r[1] = 0 ;
- r.r[2] = (int)"DBox" ;
- _kernel_swi (Wimp_ReportError, &r, &r) ;
- }
-
- catch (char *s)
- {
- _kernel_oserror err ;
- _kernel_swi_regs r ;
- err.errnum = 0 ;
- strcpy (err.errmess, s) ;
- r.r[0] = (int)&err ;
- r.r[1] = 0 ;
- r.r[2] = (int)"DBox" ;
- _kernel_swi (Wimp_ReportError, &r, &r) ;
- }
- #endif
- }
-