forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

rambling enquiry about full_mouse_input and callback_reason
Goto page 1, 2, 3, 4  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+
View previous topic :: View next topic  
Author Message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Wed Jul 18, 2012 3:09 pm    Post subject: rambling enquiry about full_mouse_input and callback_reason Reply with quote

Some years ago, I wrestled with full_mouse_input in a %gr region. At the time I was much less adept in dealing with Clearwin than I am now, and indeed, I was inter alia attempting to do things that Paul didn’t actually fix until a later version of FTN95 than I was at that time using (notably popup menus in v5.50). I recall some helpful advice given on the forum (by John Campbell among others) about fmi.
I swore (a lot!) at the time that I would never use fmi ever again, but like an alcoholic returning to the bottle, I have attempted a couple of times subsequently to use it, as there is a limit to what one can do with simple clicks and key modifiers. Indeed, the fact that one gets single mouse clicks along with double mouse clicks means that the usefulness of the single click is limited because if one ever wants to respond to a double click the single click can only be associated with something that you don’t mind being invoked en route to the double click. This makes a program idiosyncratic compared to other windows applications as a single left click is then effectively neutered.
However, without fmi, the system is very reliable, and single clicks are detected and responded to very accurately. In my most recent excursion into the minefield of fmi, I discover that code that works well without it, such as:
Code:
       CBR = CLEARWIN_STRING@('CALLBACK_REASON')
       IF (CBR .EQ. 'MOUSE_LEFT_CLICK') THEN
           Do something
       ELSE IF (CBR .EQ. 'MOUSE_RIGHT_CLICK') THEN
           Do something else
           ENDIF

occasionally misses a click with fmi enabled. This leads the user to a set of activities, such as removing fluff from the mouse or clearing other filth from its working parts, peering at the red light etc., never suspecting the true problem.
On deep reflection, it occurs to me that the original advice from John Campbell, which in effect was to quickly inspect the state of the mouse buttons and mouse coordinates at every invocation of the callback probably means handling the mouse as one did in DOS, interrupt at a time, and not relying on the above ‘callback reason’ approach. In the course of program development, that means abandoning (or at least further complicating) code that one had working satisfactorily. For me, it created a ‘slough of despond’ as I was under the impression for some reason that SET_GRAPHICS_SELECTION@ only worked with fmi. However, I find that this is not actually the case, and I wonder if something changed while I was not looking! I live in hope that eventually popup menus and scroll wheel handling will also not require fmi.
In my graphics callback routine, it would greatly simplify matters if the callback reason was set to something like ‘area_selected’ or ‘elastic_line_drawn’ as presumably one would never get a single or double click callback if SET_GRAPHICS_SELECTION@ was set to mode 1 or 2. (There appears not to be an ‘ENQUIRE_IF_GRAPHICS_AREA_SELECTION_IS_ENABLED@’ option, and at present I am keeping track of whether or not these modes are enabled using an inelegant approach with a COMMON block). Or have I missed something in the depths of FTN95.CHM?

Eddie
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Wed Jul 18, 2012 3:44 pm    Post subject: Reply with quote

Eddie,

I probably do not have to much to add to your comments.

My latest approach to coding FMI is to set up a look up table of possible responses using " call call_back_statistics (reason, 1)". I inspect this at the end of a run to see the possible call back responses that occur. There are a few I didn't expect.
Code:
 integer*4 function exit_func()
!
    call call_back_statistics (' ', -1)
!
    call close_output_window
!
    exit_func = 0
end function exit_func

Also, as I write to the screen (OUTPUT) and to files, I struggle with clashing writes with multiple call-backs and also delays in being ready to write (hence I don't report the first call-back or some of the moves.)
The other key is to skip the MOUSE_MOVE reporting until sufficient movement has occurred, say 20 pixels.
I still have not solved all these problems completely, especially the multiple writes.

The following code is the first few lines of my standard callback handling.
Code:
integer*4 function mouse_back_func()
!
! Callback to respond to %gr callback
!  reports the call back reason
!
    include <clearwin.ins>
    include <JDC_menu.ins>
    include 'crtcom.ins'
!
    integer*4 :: num_callback = 0
    integer*4 :: xs,ys, mf
    integer*4 :: xm = 0
    integer*4 :: ym = 0
    character reason*30
    logical use_1, use_98
!
    reason = clearwin_string@ ('CALLBACK_REASON')
    call get_mouse_info@ (xs, ys, mf)
!
    num_callback = num_callback + 1
    use_1  = num_callback > 1
    use_98 = num_callback > 1
!
    if (use_98) then
       write (98,*) ' '
       write (98,*) 'mouse_back_func Callback : ',reason, num_callback, xs, ys, ptr_RGB_Address
    end if
!
    call call_back_statistics (reason, 1)
!
    if ( reason == 'RESIZE') then
...
    subroutine call_back_statistics (reason, call_id)
!
     character reason*(*)
     integer*4 call_id, i
!
     integer*4, save :: num_type = 0
     integer*4, save :: num_calls(2,10)
     character, save :: reasons(10)*30
!
     if ( call_id < 1) then
!       write ( *,2000) ' Callback Statistics'
        write (98,2000) ' Callback Statistics'
        do i = 1, num_type
!          write ( *,2001) i, reasons(i), num_calls(:,i)
           write (98,2001) i, reasons(i), num_calls(:,i)
        end do
2000    format (/a)
2001    format (i4,2x,a,2i10)
     else
        do i = 1,num_type
           if (reason == reasons(i)) exit
        end do
        if ( i > 10) i = 10
        if ( i > num_type ) then
            num_type = i
            reasons(i)  = reason
            num_calls(:,i) = 0
            num_calls(call_id,i) = 1
        else
            num_calls(call_id,i) = num_calls(call_id,i) + 1
        end if
     end if
!
     end subroutine call_back_statistics
!
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Wed Jul 18, 2012 4:25 pm    Post subject: Reply with quote

John,

There's a lot to think about here! My immediate problem is to zoom in on a not very sophisticated map. Without FMI, and just using left_click to zoom in a step, right-click to zoom out, a good choice of step sizes and a limit on both zooming in and out gives me a nice effect. As my graphic is always centred in the screen, I tried a SHIFT or CTRL combo with a click to choose a new centre point. Alas, that causes an ugly jump, and my experience of other windows programs makes me yearn to be able to pan the screen view.

At that point, I contemplated scroll bars - but I dislike them for the whole of a screen-filling %gr. Maybe I should have a click-and-drag panning - but that would seem to require FMI. The logical thing for me was to use box_select, and rescale and re-centre based on that - but until I tried it earlier, I was under the impression that it required FMI as well (I'm sure it used to). It doesn't, but what it does seem to need is a way to know whether box_select is enabled, and to be able to turn it off so that simple clicks can be detected. (A mechanism for this is to select an appropriate toolbar button to swtich the process on and off, but for me, the fewer the big mouse movements and clicking on this and that, the better).

I'm fascinated by the idea of unexpected callback reasons ("There are a few I didn't expect.") How many of them are undocumented callback reasons?

Eddie

[edit]PS to Paul: could the area selection outline be a different colour, and/or the area be filled with a light tint with transparency? E
[second edit]PPS ... and wouldn't it be great if there was a mode 4 for SET_GRAPHICS_SELECTION@ in which nothing was drawn, but the start and finish coordinates of a "click and drag" operation was reported, to facilitate panning of the sort usually done with a 'hand' cursor? E
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Jul 19, 2012 1:26 am    Post subject: Reply with quote

Eddie,

My call_back_statistics is a recent work in progress.
Call_id can have a value
-1: echo statistics as end of run
1: mouse interrupt
2: mousewheel interrupt
I was thinking of storing a list of callbacks, using num_callback as the count and including cpu_clock@ as an indicator of spacing.

The main surprises I had was with resize and mouse wheel interrupts, where there were more interrupts than I expected. Also the few initial interrupts, before the program is "up and running" cause a few problems.

My blowup approach is also a work in progress (over many years), as I have a number of ideas but not the time to implement.
I do blowups with set_graphics_selection@ : mode=1. It has worked ok in the past.
I am wanting a better zoom and pan. I am thinking of using the mouse wheel to zoom in and out. To review the expanded image, I would create a virtual screen of the full object, then pan around by grabing the screen with the mouse down and draging the virtual screen over the real screen. (H:10,240xV:7,680x4colour_bytes = 300mb, hence the interest in large DIB images). Would work well for a 2D image, but needs more for rolling a 3D image.
I have a 3D roll by draging the mouse about the centre, updating with a wire diagram with the mouse down then a full rendered image when the mouse is released. I developed this over 10 years ago, so faster graphics might have meant that I could update with the rendered image, but the size of problem I have has also increased from about 50k polygons to about 20m.
With the latest problems, I don't select roll very often but do a lot of panning.
I also recently developed a lookup window; a small .1 x .1 screen in the bottom left with an edge line image. I click in this window to select a blow up view location. Works with large images and big zoom.

My call-back handler must know what viewing mode is in use: pan, blowup, rotate, porthole, wobble, lookup or other. Other is to inquire info about selected objects on the screen, so I need to know when all the other options are turned off.
Porthole is another interesting option, where I click on the full view and display a 10x blowup at that point in a .3 x .3 window in the top left. By dragging the mouse, the porthole updates in real time, with a much smaller active model.

As I'm the only user of the software, I don't have problems with tricky users who confuse the interrupt handler. I'd expect that coping with other users is another level of complexity.

I could send you my mouse.f95 if you would like to see some ideas that work for me. I'm sure there are many alternative approaches that work better. Always looking for advice on better ways to manage this. It's surprisingly easy to code some of these options, you just need to have a good idea and a way of managing the update.

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Thu Jul 19, 2012 8:19 am    Post subject: Reply with quote

I have noted this correspondence but the best I can do at the moment is to make and note to investigate when time allows.
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Jul 19, 2012 9:16 am    Post subject: Reply with quote

I will update the callback log to include the list order and elapse times.
I will try to document the first few call-backs and identify what they relate to.
Once the program starts up, I find that recalling what I did to get the call backs is difficult, but I think the first few are of interest.

I recall that if resize is enabled, there is a resize interrupt issued as the program starts. Caused me some problems, as my status variables had not been initialised. I'll investigate and provide ore reliable advice.

John
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Sat Jul 21, 2012 10:30 am    Post subject: Reply with quote

John,

As always, thanks for the ideas. Fortran programming for me is far from being my main business, and I am often reluctant to dive in too deeply, especially to shark-infested waters (like fmi)! When I have digested this I've return to the topic with my thoughts.

In the meantime, perhaps Paul will consider my suggestion for a mode 4 as it looks to me as though it would be easy to derive from modes 1 and 2, and would be of considerable use when programming panning when not using fmi.

Regards

Eddie
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Mon Jul 23, 2012 3:34 pm    Post subject: Reply with quote

Eddie,

I changed the log to store the interrupt reason and the elapse time when it occured. I also included some extra "interrupts", to log key events, as type 3.
the listing of the log, omitting repeated moves is:
Code:
 Callback listing
No  elapse  Reason                         Type
1   0.01398 saplot_first_call               3
2   0.01804 Saplot_Menus                    3
3   0.02086 RESIZE                          1
4   0.03177 plot_setup_func                 3
5   0.03178 set_Window_Size                 3
6  38.94277 MOUSE_MOVE                      1
160  46.98982 MOUSE_LEFT_CLICK                1
161  47.06987 MOUSE_MOVE                      1
202  47.82175 MOUSE_LEFT_RELEASE              1
203  48.08970 MOUSE_MOVE                      1
320  59.68949 RESIZE                          1
321  59.72217 set_Window_Size                 3
322  59.76936 RESIZE                          1
323  59.77966 set_Window_Size                 3
324  59.80108 RESIZE                          1
325  59.81080 set_Window_Size                 3
326  59.83377 RESIZE                          1
327  59.84348 set_Window_Size                 3
328  59.86597 RESIZE                          1
329  59.87586 set_Window_Size                 3
...
362  60.83729 MOUSE_MOVE                      1
457  71.03359 RESIZE                          1
458  71.03384 MOUSE_MOVE                      1
459  71.09745 set_Window_Size                 3
460  71.39687 MOUSE_MOVE                      1
804  85.70849 MOUSE_LEFT_CLICK                1
805  85.74657 MOUSE_MOVE                      1
843  86.42045 MOUSE_LEFT_RELEASE              1
844  86.89241 MOUSE_MOVE                      1
 
 Callback Statistics
   1  saplot_first_call                      0         0         1
   2  Saplot_Menus                           0         0         1
   3  RESIZE                                23         0         0
   4  plot_setup_func                        0         0         1
   5  set_Window_Size                        0         0        23
   6  MOUSE_MOVE                           827         0         0
   7  MOUSE_LEFT_CLICK                       2         0         0
   8  MOUSE_LEFT_RELEASE                     2         0         0


Note there is a RESIZE interrupt (3) at startup, before the ('%sc&', plot_setup_func) (4) has occurred. This is generated by the program startup and not user initiated.
There is a big delay from interupt 5 to 6, as the program reads the 750 mb data file.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Mon Jul 23, 2012 3:40 pm    Post subject: Reply with quote

The revised call back loging routine is:
Code:
    subroutine call_back_statistics (reason, call_id)
!
     character reason*(*)
     integer*4 call_id
!
     integer*4, parameter :: num_log = 5000
     character, save :: reason_log(num_log)*30
     real*8,    save :: reason_sec(num_log)
     integer*2, save :: reason_id(num_log)   
     integer*4, save :: log_count = 0
!
     integer*4 num_type, i, k, id
     integer*4 num_calls(3,15)
     character reasons(15)*30
!
     if ( call_id < 1) then       ! generate statistics of run
!
        write (98,2000) ' Callback listing'
        num_type  = 0
        num_calls = 0
        do k = 1,log_count
          if (.not. (k>1 .and. reason_log(k)==reason_log(k-1)) )  &
          write (98,2002) k, reason_sec(k), reason_log(k), reason_id(k)
!
          id = reason_id(k) ; if (id<1) id = 3 ; if (id>3) id = 3
          do i = 1,num_type
             if (reason_log(k) == reasons(i)) exit
          end do
          if ( i > 15) i = 15
          if ( i > num_type ) then
             num_type   = i
             reasons(i) = reason_log(k)
          end if
          num_calls(id,i) = num_calls(id,i) + 1
        end do
!
        write (98,2000) ' Callback Statistics'
        do i = 1, num_type
           write (98,2001) i, reasons(i), num_calls(:,i)
        end do
2000    format (/a)
2001    format (i4,2x,a,3i10)
2002    format (i0,f10.5,1x,a,i3)
!
     else                         ! store call-back in list
!
        if (log_count < num_log) log_count = log_count+1
        reason_log(log_count) = reason
        reason_id(log_count)  = call_id
        call ELAPSE_SECOND (reason_sec(log_count))
       
     end if
!
     end subroutine call_back_statistics
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Mon Jul 23, 2012 7:28 pm    Post subject: Reply with quote

John,

Taking 40 seconds to load the file! It is probably a good job you are your main user, or you would be programming something to keep them busy while the 40 seconds ticks by.

Thanks for your suggestions / code. When I get a spare hour or two I will revisit the hell of fmi ...

I've been drawing icons. As thumbs up and thumbs down have defeated my limited artistic abilities I've settled on smilies ...

Eddie
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Jul 26, 2012 2:04 am    Post subject: Reply with quote

Paul,

This is the first time I have been able to clearly document the effect of multiple interrupts and probably why I am getting the "write over write error"

You will note that the first 5 interrupts I have identified are :
Code:
No  elapse  Reason                         Type
1   0.01398 saplot_first_call        3 ! false interrupt as first executable line of code
2   0.01804 Saplot_Menus             3 ! false interrupt at first %mn
3   0.02086 RESIZE                   1 ! real interrupt as resize is enabled
4   0.03177 plot_setup_func          3 ! false interrupt as first %sc start
5   0.03178 set_Window_Size          3 ! false interrupt during RESIZE response


Interrupt 4 shows that %sc initialisation is being implemented while the response to the RESIZE interrupt is taking place. I presume these could be multiple threads and both groups of code can be updating the same variables.
It might not be a good thing to try, but is it possible to lock an interrupt response, so that other associated theads do not conflict. It would make the code easier to debug.
At present these two threads can conflict for I/O, where both are reporting a status u[pdate to my unit 98 log file.
I now have a better idea why the program is going wrong at startup. It does not always happen as it changes on different PC's where the relative run times of the threads change, resulting in different clashes.

Not sure what the best response to this is.

John

PS : Further to this post, I'm not sure why I use %sc at all.
I use %sc to call a variable initialisation set of routines.
Altertatively, I could call the initilisation code before any winio@ calls. Is the purpose of %sc to enable code to be run that uses routines that assume that the menu system is in place ?
I am not sure if with WINAPP if I should do a lot of computation before any winio@ calls.
What is your understanding of the timing restrictions of a startup approach ?
I'm probably making this more complex than it needs to be !
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Jul 26, 2012 2:34 am    Post subject: Reply with quote

Not sure now, as Set_Widow_Size can be called from either RESIZE or %SC, although I had assumed that RESIZE response occurred after %SC.
The startup code I use is:
Code:
program test  ! latest \PHPA_post_Dredge\saplot.new
!
use ceasap_variables
!
    include <clearwin.ins>
    include <JDC_menu.ins>
    include 'sapcom.ins'
    include 'plotcom.ins'
    include 'srcom.ins'
!
    integer*4 :: i, hwnd
    integer*4 mouse_back_func, plot_setup_func, OnMouseWheel
    external  mouse_back_func, plot_setup_func, OnMouseWheel
!
    integer*4, parameter :: WM_MOUSEWHEEL = Z'020A'
!
    character build_stamp*30
    logical full_screen
!
    call call_back_statistics ('saplot_first_call', 3)
!
      full_screen = .false. ! .true.
!
!   Initialise for no greyed options
!
      call crtstart                       !  this is called again in plot_setup_func ??
!
      include 'build.ins'
      caption     ='GHD STRUCTURES SUITE : FEA MODEL : Build date '//build_stamp
!
      i = winio@ ('%ca@&', caption)
!
      if (full_screen) then
         i = winio@ ('%ww[no_border,maximise]&')
      else
         i = winio@ ('%ww[no_border]&')
      end if
!
      i = winio@ ('%sc&', plot_setup_func)                  ! call saplot setup function
      i = winio@ ('%pv&')
!
      i = winio@ ('%`^gr[grey, user_resize, rgb_colours, full_mouse_input, user_surface]&',  &
                    1024, 768,          &   ! screen dimension when not maximised
                    ptr_RGB_Address,    &   ! screen address for rgb surface ( not sure of the order ? )
                    w_handle,           &   ! ` window handle defined in crtstart
                    mouse_back_func)        ! ^ call back function for mouse and resize
!
      i = winio@ ('%mg&', WM_MOUSEWHEEL, OnMouseWheel)      ! mousewheel response
!
      call Saplot_Menus
!
      i = winio@ ('%hw', hwnd)                              ! return the handle of the current window.
!
end program test
 
integer*4 function plot_setup_func()
!
!   Initialise structure info
!
use ceasap_variables
!
!    include <clearwin.ins>
    include <JDC_menu.ins>
    include 'sapcom.ins'
    include 'plotcom.ins'
    include 'srcom.ins'
!
    integer*4 open_func, Rotate_isoZ_func, option_update_plot, i, ilc, iauto
    external  open_func, Rotate_isoZ_func, option_update_plot
    real*8    fc
!
      call call_back_statistics ('plot_setup_func', 3)
!
      call crtstart
!
      call set_Window_Size
!
!    Initilaise SAP binary file I/O
      call initbf
!
....
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7924
Location: Salford, UK

PostPosted: Thu Jul 26, 2012 7:48 am    Post subject: Reply with quote

John

I am not able to respond to this in detail at the moment but here are a few random comments.

My understanding is that we have to think in terms of a single thread but this serves a message queue that is fed by SendMessage and PostMessage calls. The difference being that SendMessage waits for a return whilst PostMessage does not. In addition ClearWin+ can also peek a message before taking it out of the queue and processing it.

Messages can only be added to the end of the queue and processed one at a time. So the question in the end is what is the order in which the messages are sent.

Regarding %sc, I think that this is equivalent to the message WM_INITDIALOG and thus provides information whilst the window is being created by the API and before it is displayed.
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Jul 26, 2012 8:46 am    Post subject: Reply with quote

Paul,

Thanks for your response.
Based on your single thread comment, am I wrong in thinking that the first RESIZE interrupt from
winio@ ('%`^gr[grey, user_resize, rgb_colours, full_mouse_input, user_surface]&', &
could conflict with %sc ?

IN the past I have had an error that a write event has occurred while another routine has itself performed I/O ( sorry I can't recall the exact message)
I assumed this was due to a seperate thread for the interrupts.
If it is not then I will have to look for another reason and a search as to how to clean it up.

John
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Wed Aug 01, 2012 1:16 am    Post subject: Reply with quote

Paul,

I have been thinking about the problem of the relative timing of the start-up events.
%gr initiates the window state and in the example I have provided, initiates the mouse response and also the resize response.
To initialise the program settings, I call some routines before any winio@ routines (eg crtstart) and also use %sc for some other routines (via my routine plot_setup_function).
It would appear that I should change the structure of this so that I initialise all data structures not related to the %gr window before the first winio@ call and include in plot_setup_function those data structures which depend on %gr.
Also as RESIZE is initiated before the %sc response, I should check that it can work at this time, although the RESIZE response does require some of the window dimensions to be initialised. (Not being aware that this could occur has caused problems recently.)

I think the answer to this problem is to be aware of the potential timing of these events, as I suspect there is not much that can (or should) be changed.

My understanding of the mouse, resize, mouse wheel or menu interrupts is that they are separate "threads" that act independently of each other. It is important to try and minimise the coded response time so that they do not conflict. My question before is can we queue these interrupts up so that they are processed one at a time. I have had the impression that especially with MOUSE_MOVE interrupts that they do not wait for the last interrupt to be completed, which is typically found with fmi.

I would welcome your comments on any of these thoughts.

John
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+ All times are GMT + 1 Hour
Goto page 1, 2, 3, 4  Next
Page 1 of 4

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group