Source
...
Target
Commits (7)
  • Rik Griffin's avatar
    Redesigned window to show more of path. · 84527cc0
    Rik Griffin authored
    Added progress bar.
    Performance improvements, especially in 'slower' mode.
    Fixed 'count summary' bug.
    Fixed various compiler warnings.
    
    Version 0.49. Tagged as 'FilerAct-0_49'
    84527cc0
  • Rik Griffin's avatar
    Fixed progress bar bug in Filer Action. · 3d773e26
    Rik Griffin authored
    Progress bar was wrong during a CopyMove operation that required more
    memory than the available wimp slot.
    
    Version 0.50. Tagged as 'FilerAct-0_50'
    3d773e26
  • Robert Sprowson's avatar
    Didn't compile with PROGRESS_BAR turned off. · 62c87e72
    Robert Sprowson authored
    Rationalised all the switches a bit.
    Not tagged.
    62c87e72
  • Robert Sprowson's avatar
    Fix display of bytes-to-go when there are > 2G left. · b5fe2ebd
    Robert Sprowson authored
    Was doing a widening cast of a signed number to 64 bits, so showed 16 trillion bytes remaining.
    Fix templates to not say "stuff" by default in the name, as this was left on screen if an error occured before processing began.
    Things that read from clock() now use clock_t.
    Uncurled some "} else {" to match all the other files.
    Deleted the USE_LONG_LONG switch, it's been needed ever since harddiscs got bigger than 4G anyway.
    Anything assigned 'Yes' or 'No' changed to type BOOL.
    Variable 'source_of_finished_file' was signalling that a directory had been copied by setting the length to a -ve number. This has been refactored to use a BOOL instead, so files can have top bit set sizes.
    Fix bug in stack grab in count_objects_in_dir(), was grabbing an array of 2048 pointers (=8k) not 2048 bytes.
    Functions bytes_left_to_read() and bytes_left_to_write() reprototyped to return uint32_t not signed numbers.
    Still falls over copying files > 2G, but at least it gets the display right!
    
    Version 0.51. Tagged as 'FilerAct-0_51'
    b5fe2ebd
  • Robert Sprowson's avatar
    More BOOLs and things changed to C99 types. · 161f0f24
    Robert Sprowson authored
    Basically the same as version 0.51 otherwise.
    
    Version 0.52. Tagged as 'FilerAct-0_52'
    161f0f24
  • Robert Sprowson's avatar
    Swap magic constants for defines from headers. · 4b9400d5
    Robert Sprowson authored
    OS_FSControl, OS_File, OS_GBPB, OS_Args, OS_Find now use HighFSI.h.
    Indentation made more consistent.
    Variety of DEBUG macros changed to allow them to be enabled and disabled on a per-file basis.
    Put USE_RED_ERROR box switch into options.h (undefined though).
    Functionally equivalent to 0.52, but lots of diffs.
    
    Version 0.53. Tagged as 'FilerAct-0_53'
    4b9400d5
  • Robert Sprowson's avatar
    Fix to work with files > 2G. · 743fa9c2
    Robert Sprowson authored
    A good rake over the code to change filesizes to be uint32_t not ints.
    Change makefile to use StdTools.
    Shuffle icon clipping in the templates to allow for maximal numbers by moving the text a bit to the right, still fits even in system font.
    A couple more ints swapped for BOOLs.
    The memmanage code is largely unchanged and makes extensive use of signed numbers, partly because the wimpslot setting API does. This will all fall over in a big mess if the wimpslot ever gets >2G, but then the API would need changing for that to happen anyway.
    Function count_objects_in_dir swapped to use os_gbpb.
    Structure search_nest_level gains a 'counted' flag rather than signalling counting is needed by setting the filesize to -1.
    Should now be good for up to 4 billion files each of 4 billion bytes.
    
    Version 0.54. Tagged as 'FilerAct-0_54'
    743fa9c2
......@@ -30,17 +30,11 @@ EXP_HDR = <export$dir>
#
# Generic options:
#
MKDIR = cdir
AS = objasm
CC = cc
CP = copy
LD = link
RM = remove
WIPE = -wipe
DFLAGS =
include StdTools
#DFLAGS = -Ddebugfile="\"RAM::0.$.out\""
AFLAGS = -depend !Depend -Stamp -quit
CFLAGS = -c -depend !Depend -ffah ${INCLUDES} ${DFLAGS}
CFLAGS = -c -throwback -depend !Depend -ffah ${INCLUDES} ${DFLAGS}
CPFLAGS = ~cfr~v
WFLAGS = ~c~v
......@@ -130,12 +124,12 @@ install_rom: ${TARGET}
@echo ${COMPONENT}: rom module installed
clean:
${WIPE} o.* ${WFLAGS}
${WIPE} oa.* ${WFLAGS}
${WIPE} app.* ${WFLAGS}
${WIPE} rm.* ${WFLAGS}
${WIPE} linked.* ${WFLAGS}
${WIPE} map.* ${WFLAGS}
${XWIPE} o.* ${WFLAGS}
${XWIPE} oa.* ${WFLAGS}
${XWIPE} app.* ${WFLAGS}
${XWIPE} rm.* ${WFLAGS}
${XWIPE} linked.* ${WFLAGS}
${XWIPE} map.* ${WFLAGS}
${RM} ${TARGET}
${RM} s.ModuleWrap
@echo ${COMPONENT}: cleaned
......
No preview for this file type
......@@ -82,13 +82,16 @@ S:Slower
77:Stamp
78:Check
79:continue the operation
80:Paused
80a32/80a36/80a41/80a46/80a51/80a56/80a62/80a67/80a82:Paused %c%s
81:There is a %s operation in progress.
82:Writing
84:Found
85:Finished
86:%d locked item(s) not deleted
87:Disc full
87a32/87a36/87a41/87a46/87a51/87a56/87a62/87a67/87a82:Disc full when %c%s
88:Error
88a32/88a36/88a41/88a46/88a51/88a56/88a62/88a67/88a82:Error when %c%s
89:Filer Action Window
90:Options
......
No preview for this file type
......@@ -14,3 +14,4 @@
|
Set FilerAct$Path Resources:Resources.FilerAct.
UnSet Alias$Filer_Action
UnSet Alias$Filer_Action2
......@@ -13,4 +13,5 @@
| limitations under the License.
|
Set FilerAct$Path <Obey$Dir>.^.Resources.<Locale>.
Set Alias$Filer_Action2 <Obey$Dir>.^.app.FilerAct %%*0
Set Alias$Filer_Action <Obey$Dir>.^.app.FilerAct %%*0
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "0.48"
Module_Version SETA 48
Module_MajorVersion SETS "0.54"
Module_Version SETA 54
Module_MinorVersion SETS ""
Module_Date SETS "11 Jun 2009"
Module_ApplicationDate SETS "11-Jun-09"
Module_Date SETS "23 Oct 2011"
Module_ApplicationDate SETS "23-Oct-11"
Module_ComponentName SETS "FilerAct"
Module_ComponentPath SETS "castle/RiscOS/Sources/Desktop/FilerAct"
Module_FullVersion SETS "0.48"
Module_HelpVersion SETS "0.48 (11 Jun 2009)"
Module_FullVersion SETS "0.54"
Module_HelpVersion SETS "0.54 (23 Oct 2011)"
END
/* (0.48)
/* (0.54)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.48
#define Module_MajorVersion_CMHG 0.54
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 11 Jun 2009
#define Module_Date_CMHG 23 Oct 2011
#define Module_MajorVersion "0.48"
#define Module_Version 48
#define Module_MajorVersion "0.54"
#define Module_Version 54
#define Module_MinorVersion ""
#define Module_Date "11 Jun 2009"
#define Module_Date "23 Oct 2011"
#define Module_ApplicationDate "11-Jun-09"
#define Module_ApplicationDate "23-Oct-11"
#define Module_ComponentName "FilerAct"
#define Module_ComponentPath "castle/RiscOS/Sources/Desktop/FilerAct"
#define Module_FullVersion "0.48"
#define Module_HelpVersion "0.48 (11 Jun 2009)"
#define Module_LibraryVersionInfo "0:48"
#define Module_FullVersion "0.54"
#define Module_HelpVersion "0.54 (23 Oct 2011)"
#define Module_LibraryVersionInfo "0:54"
......@@ -12,8 +12,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if 0
#define debugbut
#define debugbut(k) dprintf k
#else
#define debugbut(k) /* Disabled */
#endif
#include <stdio.h>
......@@ -21,6 +24,7 @@
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <time.h>
#include "os.h"
#include "wimp.h"
......@@ -45,7 +49,7 @@
static void null_activity( action_environment * );
static void pause_operation( action_environment * );
static void continue_operation( action_environment * );
#ifdef UseFasterButton
#ifdef USE_FASTER_BUTTON
static void faster_operation( action_environment * );
#endif
static void skip_file( action_environment * );
......@@ -65,7 +69,7 @@ const button_set abort_pause_buttons =
null_activity,
null_activity,
pause_operation,
#ifdef UseFasterButton
#ifdef USE_FASTER_BUTTON
faster_operation,
#else
null_activity,
......@@ -75,7 +79,7 @@ const button_set abort_pause_buttons =
"",
"",
"4",
#ifdef UseFasterButton
#ifdef USE_FASTER_BUTTON
"FS"
#else
""
......@@ -87,7 +91,7 @@ const button_set abort_pause_buttons =
NULL,
NULL,
"6",
#ifdef UseFasterButton
#ifdef USE_FASTER_BUTTON
"F"
#else
NULL
......@@ -288,7 +292,9 @@ static void set_button( action_environment *env, int button, const char *text )
/*
Ensure button exists before setting field
*/
wimp_set_icon_state( dbox_handle, button, 0, wimp_IDELETED | wimp_IREDRAW );
wimp_iconflags flags = (wimp_iconflags) 0;
wimp_iconflags mask = (wimp_iconflags) (wimp_IDELETED | wimp_IREDRAW);
wimp_set_icon_state( dbox_handle, button, flags, mask );
dbox_setfield( env->status_box, button, msgs_lookup((char *)text) );
}
else
......@@ -304,7 +310,9 @@ static void set_button( action_environment *env, int button, const char *text )
if ( !err )
{
wimp_set_icon_state( dbox_handle, button, wimp_IDELETED | wimp_IREDRAW, wimp_IDELETED | wimp_IREDRAW );
wimp_iconflags flags = (wimp_iconflags) (wimp_IDELETED | wimp_IREDRAW);
wimp_iconflags mask = flags;
wimp_set_icon_state( dbox_handle, button, flags, mask );
r.w = dbox_handle;
r.box = icondata.box;
......@@ -337,7 +345,9 @@ void switch_buttons( action_environment *env, const button_set *new_buttons )
show_faster_stuff( env );
event_setmask( wimp_EMNULL | wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG );
wimp_emask mask = (wimp_emask) (wimp_EMNULL | wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG);
event_setmask( mask );
}
else
{
......@@ -351,16 +361,18 @@ void switch_buttons( action_environment *env, const button_set *new_buttons )
*/
read_next_node_parameters( env->test_search );
event_setmask( wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG );
wimp_emask mask = (wimp_emask) (wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG);
event_setmask( mask );
}
#ifdef UseFasterButton
#ifdef USE_FASTER_BUTTON
/* Ensure we get the buttons we really need */
if ( new_buttons == &abort_pause_buttons )
{
set_faster_state( env );
}
#endif
#endif
}
void abort_operation( action_environment *env )
......@@ -372,28 +384,22 @@ void abort_operation( action_environment *env )
static void pause_operation( action_environment *env )
{
char info_buffer[ Info_Field_Length + 10 ];
set_button( env, Misc_Button, "26" );
env->button_actions.button_helps[ Misc_Button - Abort_Button ] = "79";
env->button_actions.misc_action = continue_operation;
strcpy(info_buffer, "80a");
strcat(info_buffer, env->current_info_token);
sprintf(info_buffer, msgs_lookup(info_buffer), tolower(env->current_info[0]), &env->current_info[1]);
dbox_setfield( env->status_box, Top_Info_Field, info_buffer );
last_top_info_field = info_buffer;
set_top_info_field_with_current_info(env, "80a", "80");
dbox_showstatic( env->status_box );
event_setmask( wimp_EMNULL | wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG );
wimp_emask mask = (wimp_emask) (wimp_EMNULL | wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG );
event_setmask( mask );
}
#ifdef UseFasterButton
#ifdef USE_FASTER_BUTTON
/* JRF: Calls the same thing as the menu option */
static void faster_operation( action_environment *env )
{
......@@ -419,7 +425,7 @@ static void continue_operation( action_environment *env )
static void null_activity( action_environment *env )
{
env = env; /* keep the compiler quiet */
IGNORE(env);
}
/*
......@@ -567,9 +573,7 @@ static void view_object( action_environment *env )
*/
static void restart_operation( action_environment *env )
{
#ifdef debugbut
dprintf( "restart_operation: env=&%8X\n", (int)env );
#endif
debugbut(( "restart_operation: env=&%8X\n", (int)env ));
if ( env->action == Check_Full_Reading )
restart_file_read();
......@@ -594,7 +598,7 @@ void button_event_handler( dbox db, void *handle )
{
action_environment *env = handle;
db = db; /* keep the compiler quiet */
IGNORE(db);
switch( dbox_get( env->status_box ))
{
......
......@@ -16,16 +16,10 @@
Chain manipulation routines.
*/
#if 0
#define debugchain
#endif
#include <stdio.h>
#include "debug.h"
#ifndef __chains_h
#include "chains.h"
#endif
void chain_remove_link( chain_link *link )
{
......
......@@ -12,14 +12,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if 0
#define debuginit
#define debuginit(k) dprintf k
#else
#define debuginit(k) /* Disabled */
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <locale.h>
#include <time.h>
#include "os.h"
#include "wimp.h"
......@@ -33,7 +37,7 @@
#include "msgs.h"
#include "menu.h"
#include "Options.h"
#include "allerrs.h"
#include "malloc+.h"
#include "listfiles.h"
......@@ -66,7 +70,7 @@ static void remove_processor( void )
}
static void near_mouse_position_window( char *window_name )
{
{
template *tplt = template_find( window_name );
wimp_mousestr ptr;
os_error *err;
......@@ -105,15 +109,15 @@ static wimp_msgaction Messages[] = {
wimp_MFilerAddSelection,
wimp_MFilerAction,
wimp_MFilerControlAction,
0
wimp_MCLOSEDOWN /* list terminator (0, but with the right type) */
};
os_error *initialise( action_environment *env, int argc, char *argv[] )
{
os_error *err;
argc = argc; /* keep the compiler quiet */
argv = argv; /* keep the compiler quiet */
IGNORE(argc); /* keep the compiler quiet */
IGNORE(argv); /* keep the compiler quiet */
overflowing_initialise();
......@@ -125,20 +129,22 @@ os_error *initialise( action_environment *env, int argc, char *argv[] )
wimpt_messages(Messages);
wimpt_init(msgs_lookup("89"));
template_init();
debuginit(( "Resources initialised\n" ));
#ifdef debuginit
#ifdef debug
/* Test errors. */
{ os_error *err;
{
os_error *err;
err = error( mb_slotsize_too_small );
dprintf("%d: %s\n", err->errnum, err->errmess);
debuginit(( "%d: %s\n", err->errnum, err->errmess ));
err = error( mb_malloc_failed );
dprintf("%d: %s\n", err->errnum, err->errmess);
debuginit(( "%d: %s\n", err->errnum, err->errmess ));
err = error( mb_unexpected_state );
dprintf("%d: %s\n", err->errnum, err->errmess);
debuginit(( "%d: %s\n", err->errnum, err->errmess ));
err = error( mb_broken_templates );
dprintf("%d: %s\n", err->errnum, err->errmess);
debuginit(( "%d: %s\n", err->errnum, err->errmess ));
}
#endif
#endif
/*
Get the memmanagement onto the right footing
......@@ -150,7 +156,7 @@ os_error *initialise( action_environment *env, int argc, char *argv[] )
/*
re-position the window near the mouse
*/
near_mouse_position_window( Main_Window );
near_mouse_position_window( MAIN_TEMPLATE_NAME );
/*
start up the dbox wimplib stuff
......@@ -165,11 +171,12 @@ os_error *initialise( action_environment *env, int argc, char *argv[] )
atexit( remove_processor );
/*
create a window for ourselved
create a window for ourself
*/
env->status_box = dbox_new( Main_Window );
env->status_box = dbox_new( MAIN_TEMPLATE_NAME );
if ( env->status_box == NULL )
return error( mb_broken_templates );
env->window_handle = dbox_syshandle( env->status_box );
/*
Attach the button event handler
......@@ -177,7 +184,7 @@ os_error *initialise( action_environment *env, int argc, char *argv[] )
dbox_eventhandler( env->status_box, button_event_handler, env );
/*
Give ourselves a menu
Give ourself a menu
*/
env->option_menu = menu_new( msgs_lookup( "90" ), msgs_lookup( "91" ));
if ( env->option_menu == NULL )
......@@ -197,7 +204,7 @@ os_error *initialise( action_environment *env, int argc, char *argv[] )
/*
Enable only those events we're interested in
*/
event_setmask( wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG );
event_setmask( (wimp_emask)(wimp_EMPTRLEAVE | wimp_EMPTRENTER | wimp_EMUSERDRAG) );
/*
Initialise an empty search context and boxchange information.
......@@ -208,10 +215,12 @@ os_error *initialise( action_environment *env, int argc, char *argv[] )
env->flex_memory = No;
env->disable_flex = No;
env->in_error = No;
#ifdef USE_PROGRESS_BAR
env->progress = 0;
#endif
last_top_info_field = NULL;
/*
Make sure we don't go away when the window's closed
*/
......
......@@ -15,7 +15,7 @@
/*
Control the Filer's action window.
This code compilers into a relocatable module which controls the Filer's
This code compiles into a relocatable module which controls the Filer's
action window.
0.00 08-May-89 JSR Copied from allfiles - a 'list all files matching
......@@ -100,7 +100,9 @@ action window.
*/
#if 0
#define debugact
#define debugact(k) dprintf k
#else
#define debugact(k) /* Disabled */
#endif
#include <stdio.h>
......@@ -110,10 +112,12 @@ action window.
#include <time.h>
#include <ctype.h>
/* AMcC 22-Jul-94 include swis.h rather than arthur.h !! */
#include "Global/FSNumbers.h"
#include "Interface/HighFSI.h"
#include "swis.h"
#include "os.h"
#include "akbd.h"
#include "wimp.h"
#include "wimpt.h"
#include "werr.h"
......@@ -148,23 +152,18 @@ action window.
#define Option_FilerAction_ConfirmDeletes 0x00000020 /* RML */
#define Option_FilerAction_Faster 0x00000040 /* RML */
/* AMcC: 22-Jul-94 - Shouldn't be defined here
* #define FilerAction_SendSelectedDirectory 0x88000
* #define FilerAction_SendSelectedFile 0x88001
* #define FilerAction_SendStartOperation 0x88002
*/
#ifdef USE_STATUS_IN_TITLE
static char TitleString[64];
#endif
static char PathString[ Top_Info_Field_Length + 1 ];
#define FileChar_ManyAny '*'
#define FileChar_Any '#'
#define FileSystemNumber_NetFS 5
#define HELP_MESSAGE_CONTROL_NOBUTTON "1"
#define HELP_MESSAGE_CONTROL "2"
#define QUERY_TEMPLATE_NAME "query"
/*
A chain link structure
......@@ -189,13 +188,12 @@ typedef struct
*/
extern os_error *i_am_now_active( void );
#define Yes 1
#define No 0
#define Max_Invocation_Name_Length 20
#define Yes (!No)
/* AMcC: 22-Jul-94 - defined in swis.h
* #define OS_ExitAndDie 0x50
*/
#define SPACE ' '
#define Max_Invocation_Name_Length 20
/*
* Field masks for date stamping
......@@ -203,22 +201,13 @@ extern os_error *i_am_now_active( void );
#define DateStamped_Mask 0xfff00000
#define DateStamp_HighByte 0x000000ff
#define Attribute_OwnerRead 0x00000001
#define Attribute_OwnerWrite 0x00000002
#define Attribute_Locked 0x00000008
#define Attribute_PublicRead 0x00000010
#define Attribute_PublicWrite 0x00000020
#define SPACE ' '
#define max(a,b) ((a)>(b)?(a):(b))
/*
Status indications
*/
action_environment env;
char *last_top_info_field;
static int doings_time = (10*CLK_TCK)/100;
const char *last_top_info_field;
static clock_t doings_time = (10*CLK_TCK)/100;
static int UpdatePath = 0, UpdateTop = 0, UpdateBottom = 0;
#define Number_Of_Actions 10
#define Number_Of_Icon_Strings 5
......@@ -230,20 +219,26 @@ static int doings_time = (10*CLK_TCK)/100;
static char *icon_strings[ Number_Of_Actions ][ Number_Of_Icon_Strings ] =
{
/* title top progress bottom progress top info help action */
/* title top bottom top info help action */
/* progress progress */
{ "29", "30", "31", "32", "33" }, /* copying */
{ "34", "30", "35", "36", "37" }, /* moving (renaming) */
{ "38", "39", "40", "41", "42" }, /* deleting */
{ "43", "44", "45", "46", "47" }, /* setting access */
{ "48", "49", "50", "51", "52" }, /* settype */
{ "53", "54", "55", "56", "57" }, /* count */
{ "34", "30", "35", NULL/*36*/, "37" }, /* moving (renaming) */
{ "38", "39", "40", NULL/*41*/, "42" }, /* deleting */
{ "43", "44", "45", NULL/*46*/, "47" }, /* setting access */
{ "48", "49", "50", NULL/*51*/, "52" }, /* settype */
{ "53", "54", "55", NULL/*56*/, "57" }, /* count */
{ "34", "30", "58", "32", "37" }, /* copy/moving */
{ "29", "30", "31", "32", "33" }, /* copy local */
{ "59", "60", "61", "62", "63" }, /* stamp */
{ "64", "65", "66", "67", "68" } /* find */
{ "59", "60", "61", NULL/*62*/, "63" }, /* stamp */
{ "64", "65", "66", NULL/*67*/, "68" } /* find */
};
static int show_when_faster[ Number_Of_Actions ][2] =
/*
Changed this so we show everything in faster mode, except the "bytes to go"
field in a copy operation
*/
static BOOL show_when_faster[ Number_Of_Actions ][2] =
{
/* top progress bottom progress action */
{ No, Yes }, /* copying */
......@@ -251,11 +246,11 @@ static int show_when_faster[ Number_Of_Actions ][2] =
{ Yes, Yes }, /* deleting */
{ Yes, Yes }, /* setting access */
{ Yes, Yes }, /* settype */
{ No, No }, /* count */
{ Yes, Yes }, /* count */
{ No, Yes }, /* copy/moving */
{ No, Yes }, /* copy local */
{ Yes, Yes }, /* stamp */
{ Yes, No } /* find */
{ Yes, Yes } /* find */
};
static char *action_prompt[] =
......@@ -272,6 +267,29 @@ static char *action_prompt[] =
"78"
};
#ifdef debug
static char *debug_operation(int op)
{
switch (op)
{
case Action_Copying : return "Action_Copying";
case Action_Moving : return "Action_Moving";
case Action_Deleting : return "Action_Deleting";
case Action_Setting_Access : return "Action_Setting_Access";
case Action_Setting_Type : return "Action_Setting_Type";
case Action_Counting : return "Action_Counting";
case Action_CopyMoving : return "Action_CopyMoving";
case Action_CopyLocal : return "Action_CopyLocal";
case Action_Stamping : return "Action_Stamping";
case Action_Finding : return "Action_Finding";
}
return "unknown";
}
#else
#define debug_operation(op) NULL
#endif
/* RML */
static void hide_faster_stuff( action_environment *env );
......@@ -279,7 +297,7 @@ static void hide_faster_stuff( action_environment *env );
Establish a delayed switch on/off for the dbox.
Delay is in centiseconds
*/
/*static*/ void switch_dbox_on_off( action_environment *env, int direction, int delay )
void switch_dbox_on_off( action_environment *env, int direction, int delay )
{
env->time_to_boxchange = clock() + (delay * CLK_TCK)/100;
env->boxchange_direction = direction;
......@@ -335,68 +353,195 @@ static int caseless_wildcmp( const char *a, const char *b )
return 0;
}
static char newpath[ Info_Field_Length + 1 ];
static char newleaf[ 10 + 1 ];
/*
Set the content of the bottom info field from the file name
Set the status text displayed in the top field, or the title bar
*/
static void set_bottom_info_field( action_environment *env, char *text )
static void set_top_info_field_raw(action_environment *env, char *text)
{
char *leaf;
#ifdef USE_STATUS_IN_TITLE
if (text != NULL)
{
char title[256];
if ( text == NULL )
return;
sprintf(title, "%s - %s", TitleString, text);
win_settitle( env->window_handle, title );
}
else
{
win_settitle( env->window_handle, TitleString );
}
#else
if (text == NULL) text = "";
dbox_setfield( env->status_box, Top_Info_Field, text );
#endif
last_top_info_field = text;
}
/* Split text into path and leafname */
leaf = strrchr( text, '.' );
if ( leaf != NULL )
/*
Set the status text, from a token in the messages file
*/
static void set_top_info_field(action_environment *env, char *token)
{
char *text = NULL;
if (token != NULL && token[0] != '\0')
{
leaf += 1;
text = msgs_lookup( token );
}
set_top_info_field_raw(env, text);
}
if ( leaf - text > Info_Field_Length )
void set_top_info_field_with_current_info(action_environment *env, char *token1, char *token2)
{
if (env->current_info_token != NULL)
{
strncpy( newpath, leaf - Info_Field_Length, Info_Field_Length );
newpath[ Info_Field_Length ] = '\0';
char buffer[Top_Info_Field_Length];
strcpy(buffer, token1);
strcat(buffer, env->current_info_token);
sprintf(buffer, msgs_lookup(buffer), tolower(env->current_info[0]), &env->current_info[1]);
set_top_info_field_raw(env, buffer);
}
else
{
strncpy( newpath, text, leaf - text );
newpath[ leaf - text ] = '\0';
set_top_info_field(env, token2);
}
}
/*
Set the content of the path display from the file name.
We no longer split the path into two parts, as the display field has been made wider.
*/
static void set_bottom_info_field( action_environment *env, char *text )
{
int l;
IGNORE(env);
if ( text == NULL )
return;
if ((l = strlen(text)) > Top_Info_Field_Length)
{
strncpy(PathString, text + l - Top_Info_Field_Length, Top_Info_Field_Length);
PathString[Top_Info_Field_Length] = '\0';
}
else
{
*newpath = '\0';
leaf = text;
strcpy(PathString, text);
}
strncpy( newleaf, leaf, 10 );
newleaf[ 10 ] = '\0';
UpdatePath = 1;
}
static void set_top_progress_field( action_environment *env, uint64_t value )
{
env->top_progress = value;
UpdateTop = 1;
}
/*
Add a value to top progress. Instead of directly updating the icon, we set a flag
that causes it to be updated on the next null poll.
*/
static void more_top_progress( action_environment *env, uint32_t change )
{
env->top_progress += change;
UpdateTop = 1;
}
/*
Add a value to bottom progress. Instead of directly updating the icon, we set a flag
that causes it to be updated on the next null poll.
*/
static void more_bottom_progress( action_environment *env, uint32_t change )
{
env->bottom_progress += change;
UpdateBottom = 1;
}
if ( !env->faster )
#ifdef USE_PROGRESS_BAR
/*
Add a value to the progress indicator
*/
static void add_progress(action_environment *env, uint32_t progress, char *text)
{
env->progress += progress;
if (env->progress > INT32_MAX) env->progress = INT32_MAX;
if (text != NULL)
{
dbox_setfield( env->status_box, Bottom_Info_Path, newpath );
dbox_setfield( env->status_box, Bottom_Info_Leaf, newleaf );
debugact(( "%s: +%08x -> %08x\n", text, progress, env->progress ));
}
}
#ifdef USE_LONG_LONG
static void set_top_progress_field( action_environment *env, uintmax_t value )
#else
static void set_top_progress_field( action_environment *env, unsigned value )
#endif
/*
Show the current progress indicator. Called on null poll events.
The first time this is called, we calculate how much progress is represented by
one OS unit. The Progress_Bar icon is then resized to be a proportion of the total
size of the Progress_Bar_BBox icon.
*/
static void update_progress_bar(action_environment *env)
{
env->top_progress = value;
if ( !env->faster || show_when_faster[ env->operation ][ 0 ] )
dbox_setlongnumeric( env->status_box, Top_Progress_Field, value );
static int ppos = 0, max = 0, last = 0;
static wimp_icon i;
int w, size;
os_regset r;
w = dbox_syshandle( env->status_box );
if (ppos == 0)
{
wimp_icon b;
if (wimp_get_icon_info(w, Progress_Bar, &i) != NULL) return;
if (wimp_get_icon_info(w, Progress_Bar_BBox, &b) != NULL) return;
max = b.box.x1 - b.box.x0;
ppos = INT32_MAX / max; /* progress per os unit */
i.box = b.box;
}
size = env->progress / ppos + 2;
if (size > max) size = max;
if (size >= last && size < last + 2)
return; /* no change from last time */
i.box.x1 = i.box.x0 + size;
r.r[0] = w;
r.r[1] = Progress_Bar;
r.r[2] = i.box.x0;
r.r[3] = i.box.y0;
r.r[4] = i.box.x1;
r.r[5] = i.box.y1;
os_swix( Wimp_ResizeIcon, &r );
wimp_set_icon_state(w, Progress_Bar, (wimp_iconflags)0, (wimp_iconflags)0);
last = size;
debugact(( "update_progress_bar: %08x -> %d / %d\n", env->progress, size, max ));
}
#endif
static void switch_box_to_error( action_environment *env, os_error *err )
{
wimp_openstr o;
template *tplt = template_find( Main_Window );
template *tplt = template_find( MAIN_TEMPLATE_NAME );
int xw;
int yw;
......@@ -422,10 +567,11 @@ static void switch_box_to_error( action_environment *env, os_error *err )
wimpt_noerr( wimp_open_wind( &o ));
}
static void switch_box_from_error( action_environment *env )
{
wimp_wstate s;
template *tplt = template_find( Main_Window );
template *tplt = template_find( MAIN_TEMPLATE_NAME );
int xw;
int yw;
......@@ -444,6 +590,7 @@ static void switch_box_from_error( action_environment *env )
wimpt_noerr( wimp_open_wind( &s.o ));
}
void switch_to_reading( action_environment *env )
{
env->current_info = msgs_lookup( "32" );
......@@ -456,6 +603,7 @@ void switch_to_reading( action_environment *env )
env->action = Check_Full_Reading;
}
/*
Acknowledge a message
*/
......@@ -465,16 +613,19 @@ static os_error *ack_message( wimp_eventstr *event )
return wimp_sendmessage( wimp_EACK, &event->data.msg, event->data.msg.hdr.task );
}
static int menus_greyed[ 3 ][ 5 ] =
static BOOL menus_greyed[ 3 ][ 5 ] =
{
{ No, No, No, No, No },
{ No, No, No, No, Yes },
{ No, Yes, No, Yes, Yes }
};
typedef enum {none, name, access, type } destination_type;
typedef enum {mt_all, mt_notcopy, mt_information } menu_type;
static struct start_up_details_str
{
int init_for_copy:1;
......@@ -518,14 +669,26 @@ static os_error *start_operation( action_environment *env, actions_possible oper
os_error *err;
env->operation = operation;
debugact(( "new operation: %s\n", debug_operation( env->operation ) ));
dbox_setfield( env->status_box, Top_Progress_Line, msgs_lookup( icon_strings[ operation ][ Top_Progress_Line_Text ] ));
dbox_setfield( env->status_box, Bottom_Progress_Line, msgs_lookup( icon_strings[ operation ][ Bottom_Progress_Line_Text ] ));
#ifdef USE_STATUS_IN_TITLE
strcpy(TitleString, msgs_lookup( icon_strings[ operation ][ Title_Text ] ));
win_settitle( env->window_handle, TitleString );
#else
win_settitle( dbox_syshandle( env->status_box ), msgs_lookup( icon_strings[ operation ][ Title_Text ] ));
#endif
env->top_progress = 0;
env->bottom_progress = 0;
dbox_setlongnumeric( env->status_box, Top_Progress_Field, env->top_progress );
dbox_setlongnumeric( env->status_box, Bottom_Progress_Field, env->bottom_progress );
#ifdef USE_PROGRESS_BAR
env->progress = 0;
update_progress_bar(env);
#endif
env->faster = No;
env->faster_stuff_hidden = No;
......@@ -589,9 +752,7 @@ static os_error *start_operation( action_environment *env, actions_possible oper
case type:
env->new_type = *(int *)auxilliary_information;
#ifdef debugact
dprintf( "new type is %d\n", env->new_type );
#endif
debugact(( "new type is %d\n", env->new_type ));
break;
default:
......@@ -617,9 +778,9 @@ static os_error *start_operation( action_environment *env, actions_possible oper
/* drop through into... */
case Action_Finding:
#ifndef CONFIRM_MEANS_CONFIRM_ALL
#ifndef CONFIRM_MEANS_CONFIRM_ALL
env->confirm = No;
#endif
#endif
/* drop through into... */
case Action_Stamping:
......@@ -651,7 +812,7 @@ static os_error *start_operation( action_environment *env, actions_possible oper
if ( err || first_nodename == NULL )
break;
r.r[0] = 13; /* lookup FS */
r.r[0] = FSControl_LookupFS;
r.r[1] = (int) first_nodename;
r.r[2] = 0; /* truncate on . or : etc */
......@@ -662,8 +823,8 @@ static os_error *start_operation( action_environment *env, actions_possible oper
/*
NetFS doesn't like OwnerWrite being set on directories.
*/
if ( !err && r.r[1] == FileSystemNumber_NetFS )
env->directory_access_setting_mask &= ~Attribute_OwnerWrite;
if ( !err && r.r[1] == fsnumber_net )
env->directory_access_setting_mask &= ~write_attribute;
break;
}
......@@ -677,6 +838,7 @@ static os_error *start_operation( action_environment *env, actions_possible oper
return NULL;
}
static void go_verbose( action_environment *env )
{
wimp_wstate state;
......@@ -695,6 +857,7 @@ static void go_verbose( action_environment *env )
env->boxchange_direction = 0;
}
/* JRF: Toggle the faster operation of the window.
This is accessed from the Buttons.c source.
*/
......@@ -716,6 +879,7 @@ void toggle_faster( action_environment *env )
menu_setflags( env->option_menu, 1, env->faster, menus_greyed[ start_up_details[ env->operation ].men ][ 0 ] );
}
static void go_terse( action_environment *env )
{
env->verbose = No;
......@@ -757,6 +921,7 @@ static void control_action( action_environment *env, wimp_eventstr *event )
}
}
/*
Message processor
*/
......@@ -795,35 +960,27 @@ BOOL message_event_handler( wimp_eventstr *event, void *environment )
switch( dboxquery( query_message ) )
{
case dboxquery_YES:
#ifdef debugact
dprintf("Discard selected\n");
#endif
debugact(( "Discard selected\n" ));
if (!(size_of_prequit > sizeof(wimp_msghdr) && flags_of_prequit & 1))
{
wimp_get_caret_pos( &event->data.key.c );
event->data.key.chcode = 0x1fc; /* ctrl/shft/f12 */
event->data.key.chcode = akbd_Ctl | akbd_Sh | akbd_Fn12;
wimp_sendmessage( wimp_EKEY, (wimp_msgstr *)&event->data, sender );
#ifdef debugact
dprintf("sent message to &%x\n",sender);
#endif
debugact(( "sent message to &%x\n",sender ));
}
abort_operation( env );
break;
case dboxquery_NO:
case dboxquery_CANCEL:
#ifdef debugact
dprintf("Cancel selected\n");
#endif
debugact(( "Cancel selected\n" ));
break;
}
}
break;
case wimp_MSETSLOT:
#ifdef debugact
dprintf( "Slot(%d,%d) - T=%d\n", event->data.msg.data.words[0],event->data.msg.data.words[1], wimpt_task() );
#endif
debugact(( "Slot(%d,%d) - T=%d\n", event->data.msg.data.words[0],event->data.msg.data.words[1], wimpt_task() ));
if ( !env->disable_flex )
{
if ( event->data.msg.data.words[1] == wimpt_task() )
......@@ -857,8 +1014,7 @@ dprintf( "Slot(%d,%d) - T=%d\n", event->data.msg.data.words[0],event->data.msg.d
case Skip_Button:
sprintf( event->data.msg.data.helpreply.text, msgs_lookup( HELP_MESSAGE_CONTROL ),
msgs_lookup( icon_strings[ env->operation ][ Help_Message_Operation_Fillin ] ),
msgs_lookup( env->button_actions.button_helps[
event->data.msg.data.helprequest.m.i - Abort_Button ] ));
msgs_lookup( env->button_actions.button_helps[ event->data.msg.data.helprequest.m.i - Abort_Button ] ));
break;
default:
......@@ -876,7 +1032,7 @@ dprintf( "Slot(%d,%d) - T=%d\n", event->data.msg.data.words[0],event->data.msg.d
env->source_directory_name_length = strlen( event->data.msg.data.chars );
break;
#ifdef USE_LOAD_OPERATIONS
#ifdef USE_LOAD_OPERATIONS
case wimp_MDATALOAD:
if ((env->operation != Action_Copying) &&
(env->operation != Action_Moving) &&
......@@ -904,7 +1060,7 @@ dprintf( "Slot(%d,%d) - T=%d\n", event->data.msg.data.words[0],event->data.msg.d
}
}
break;
#endif
#endif
case wimp_MFilerAddSelection:
{
......@@ -980,47 +1136,43 @@ dprintf( "Slot(%d,%d) - T=%d\n", event->data.msg.data.words[0],event->data.msg.d
return processed;
}
/*
Because the display of fields is more efficient, we don't hide everything in faster mode
*/
static void hide_faster_stuff( action_environment *env )
{
if ( env->faster && !env->faster_stuff_hidden )
{
dbox_setfield( env->status_box, Bottom_Info_Path, "" );
dbox_setfield( env->status_box, Bottom_Info_Leaf, "" );
if ( !show_when_faster[ env->operation ][ 0 ] )
dbox_setfield( env->status_box, Top_Progress_Field, "-" );
if ( !show_when_faster[ env->operation ][ 1 ] )
dbox_setfield( env->status_box, Bottom_Progress_Field, "-" );
env->faster_stuff_hidden = Yes;
/* JRF: Make the 'Faster' button show 'Slower' now */
set_faster_state ( env );
}
}
void show_faster_stuff( action_environment *env )
{
if ( env->faster_stuff_hidden )
{
dbox_setfield( env->status_box, Bottom_Info_Path, newpath );
dbox_setfield( env->status_box, Bottom_Info_Leaf, newleaf );
if ( !show_when_faster[ env->operation ][ 0 ] )
dbox_setlongnumeric( env->status_box, Top_Progress_Field, env->top_progress );
if ( !show_when_faster[ env->operation ][ 1 ] )
{
dbox_setlongnumeric( env->status_box, Bottom_Progress_Field, env->bottom_progress );
/* char buf[20]; */
/* sprintf(buf,"%u",env->bottom_progress); */
/* dbox_setfield( env->status_box, Bottom_Progress_Field, buf ); */
}
env->faster_stuff_hidden = No;
/* JRF: Make the 'Faster' button show 'Faster' now */
set_faster_state( env );
}
}
void option_menu_handler( action_environment *env, char *hit )
{
switch( hit[0] )
......@@ -1056,6 +1208,7 @@ void option_menu_handler( action_environment *env, char *hit )
reflect_menu_flags( env );
}
void switch_to_writing( action_environment *env )
{
env->current_info = msgs_lookup( "82" );
......@@ -1137,17 +1290,14 @@ static os_error *create_destination_localfile( action_environment *env, char *so
}
else
{
*destination = overflowing_malloc( env->source_directory_name_length + 1 + strlen( env->destination_name ) +
strlen( sourcegunge ) + 1 );
*destination = overflowing_malloc( env->source_directory_name_length + 1 + strlen( env->destination_name ) + strlen( sourcegunge ) + 1 );
if ( *destination == NULL )
return error( mb_malloc_failed );
strncpy( *destination, source, env->source_directory_name_length + 1 );
sprintf( *destination + env->source_directory_name_length + 1, "%s%s",
env->destination_name,
sourcegunge );
sprintf( *destination + env->source_directory_name_length + 1, "%s%s", env->destination_name, sourcegunge );
}
return NULL;
......@@ -1174,7 +1324,7 @@ static os_error *create_destination_filename( action_environment *env, char *sou
/*
Add next file to read list
*/
static os_error *test_add_to_read_list( action_environment *env, int *should_be_added )
static os_error *test_add_to_read_list( action_environment *env, BOOL *should_be_added )
{
char *destination;
char *source;
......@@ -1201,12 +1351,12 @@ static os_error *test_add_to_read_list( action_environment *env, int *should_be_
*/
if ( env->looknewer &&
( source_reload & DateStamped_Mask ) == DateStamped_Mask &&
objecttype_of_next_node( env->test_search ) != ObjectType_Directory )
objecttype_of_next_node( env->test_search ) != object_directory )
{
/*
Get the destination's information
*/
fileplace.action = 5; /* read catalogue information */
fileplace.action = OSFile_ReadInfo;
fileplace.name = destination;
err = os_file( &fileplace );
......@@ -1265,7 +1415,7 @@ static os_error *test_add_to_read_list( action_environment *env, int *should_be_
/*
This actually adds the next file to the read list.
*/
static void add_to_read_list( action_environment *env, int *i_am_full )
static void add_to_read_list( action_environment *env, BOOL *i_am_full )
{
char *destination;
char *source;
......@@ -1288,7 +1438,12 @@ static void add_to_read_list( action_environment *env, int *i_am_full )
attributes_of_next_node( env->test_search ),
objecttype_of_next_node( env->test_search ),
env->force,
i_am_full ));
i_am_full
#ifdef USE_PROGRESS_BAR
, progress_of_next_node( env->test_search )
, chain_ref_ptr_of_next_node(env->test_search)
#endif
));
overflowing_free( destination );
overflowing_free( source );
......@@ -1296,29 +1451,6 @@ static void add_to_read_list( action_environment *env, int *i_am_full )
switch_to_reading( env );
}
/*
Record more top progress
*/
static void more_top_progress( action_environment *env, int change )
{
env->top_progress += change;
set_top_progress_field( env, env->top_progress );
}
/*
Record more bottom progress
*/
static void more_bottom_progress( action_environment *env, unsigned int change )
{
env->bottom_progress += change;
if ( !env->faster || show_when_faster[ env->operation ][ 1 ] )
{
dbox_setlongnumeric( env->status_box, Bottom_Progress_Field, env->bottom_progress);
/* char buf[20]; */
/* sprintf(buf,"%u",env->bottom_progress); */
/* dbox_setfield( env->status_box, Bottom_Progress_Field, buf ); */
}
}
/*
Get the access of a file
......@@ -1328,7 +1460,7 @@ static os_error *get_access_to_file( char *filename, int *access )
os_error *err;
os_filestr fileplace;
fileplace.action = 5; /* get file attributes */
fileplace.action = OSFile_ReadInfo;
fileplace.name = filename;
err = os_file( &fileplace );
......@@ -1337,6 +1469,7 @@ static os_error *get_access_to_file( char *filename, int *access )
return err;
}
/*
Set the access to any file
*/
......@@ -1344,25 +1477,27 @@ static os_error *set_access_to_file( char *filename, int access )
{
os_filestr fileplace;
fileplace.action = 4; /* set file attributes */
fileplace.action = OSFile_WriteAttr;
fileplace.name = filename;
fileplace.end = access;
return os_file( &fileplace );
}
/*
Attempt to delete a node
*/
static os_error *delete_node(char *name)
{
os_filestr fileplace;
fileplace.action = 6; /* delete object */
fileplace.action = OSFile_Delete;
fileplace.name = name;
return os_file( &fileplace );
}
/*
Set the access of next node
*/
......@@ -1383,6 +1518,7 @@ static os_error *set_access( action_environment *env, int access )
return err;
}
/*
Stamp any file
*/
......@@ -1390,12 +1526,13 @@ static os_error *stamp_file( char *filename )
{
os_filestr fileplace;
fileplace.action = 9; /* stamp file */
fileplace.action = OSFile_SetStamp;
fileplace.name = filename;
return os_file( &fileplace );
}
/*
Stamp next node
*/
......@@ -1416,6 +1553,7 @@ static os_error *stamp( action_environment *env )
return err;
}
/*
Do a rename
*/
......@@ -1425,17 +1563,15 @@ static os_error *riscos_rename( action_environment *env )
os_regset r;
char *source;
char *destination;
int should_be_added;
BOOL should_be_added;
test_add_to_read_list(env, &should_be_added);
wimpt_noerr( next_nodename( env->test_search, &source ));
if (!should_be_added) return 0;
wimpt_noerr( create_destination_filename( env, source, &destination ));
#ifdef debugact
dprintf("riscos_rename: src = %s, dest = %s\n",source,destination);
#endif
r.r[0] = 25; /* rename */
debugact(( "riscos_rename: src = %s, dest = %s\n",source,destination ));
r.r[0] = FSControl_Rename;
r.r[1] = (int)source;
r.r[2] = (int)destination;
......@@ -1447,14 +1583,20 @@ dprintf("riscos_rename: src = %s, dest = %s\n",source,destination);
return err;
}
static os_error *Do_Next_File( action_environment *env )
{
os_error *err;
char *filename;
int inhibit_confirm = No;
int is_cvs_directory = No;
BOOL inhibit_confirm = No;
BOOL is_cvs_directory = No;
uint32_t p = 0;
err = step_to_next_node( env->test_search );
err = step_to_next_node( env->test_search, &p);
#ifdef USE_PROGRESS_BAR
add_progress(env, p, "Do_Next_File");
#endif
if ( err )
return err;
......@@ -1468,7 +1610,8 @@ static os_error *Do_Next_File( action_environment *env )
set_bottom_info_field( env, filename );
if ( env->auto_skip_cvs ) {
if ( env->auto_skip_cvs )
{
size_t length = strlen( filename );
if (length > 4 && strcmp(filename + length - 4, ".CVS") == 0)
{
......@@ -1500,7 +1643,7 @@ static os_error *Do_Next_File( action_environment *env )
break;
case Action_CopyMoving:
if ( objecttype_of_next_node( env->test_search ) == ObjectType_Directory &&
if ( objecttype_of_next_node( env->test_search ) == object_directory &&
directory_is_after_contents( env->test_search ) )
{
env->action = Add_To_Read_List;
......@@ -1513,7 +1656,7 @@ static os_error *Do_Next_File( action_environment *env )
break;
case Action_Deleting:
if ( objecttype_of_next_node( env->test_search ) == ObjectType_Directory )
if ( objecttype_of_next_node( env->test_search ) == object_directory )
{
if ( directory_is_after_contents( env->test_search ) )
{
......@@ -1542,6 +1685,10 @@ static os_error *Do_Next_File( action_environment *env )
case Action_Counting:
more_top_progress( env, 1 );
more_bottom_progress( env, size_of_next_node( env->test_search ) );
#ifdef USE_PROGRESS_BAR
add_progress(env, progress_of_next_node(env->test_search), "Action_Counting");
#endif
break;
case Action_Stamping:
......@@ -1551,11 +1698,11 @@ static os_error *Do_Next_File( action_environment *env )
case Action_Finding:
if ( !caseless_wildcmp( env->destination_name, name_of_next_node( env->test_search )) )
{
last_top_info_field = msgs_lookup( "84" );
dbox_setfield( env->status_box, Top_Info_Field, last_top_info_field );
if ( (objecttype_of_next_node( env->test_search ) == ObjectType_Directory &&
set_top_info_field( env, "84" );
if ( (objecttype_of_next_node( env->test_search ) == object_directory &&
name_of_next_node( env->test_search )[0] != '!') ||
objecttype_of_next_node( env->test_search ) == (ObjectType_Directory | ObjectType_File) )
objecttype_of_next_node( env->test_search ) == (object_directory | object_file) )
{
switch_buttons( env, &open_buttons );
}
......@@ -1568,7 +1715,7 @@ static os_error *Do_Next_File( action_environment *env )
/*
Keep the user informed of what's happening
*/
if ( objecttype_of_next_node( env->test_search ) != ObjectType_File )
if ( objecttype_of_next_node( env->test_search ) != object_file )
{
more_top_progress( env, 1 );
}
......@@ -1576,6 +1723,11 @@ static os_error *Do_Next_File( action_environment *env )
{
more_bottom_progress( env, 1 );
}
#ifdef USE_PROGRESS_BAR
add_progress(env, progress_of_next_node(env->test_search), "Action_Finding");
#endif
break;
default:
......@@ -1590,8 +1742,7 @@ static os_error *Do_Next_File( action_environment *env )
!inhibit_confirm )
{
switch_buttons( env, &confirm_buttons );
last_top_info_field = msgs_lookup( action_prompt[ env->operation ] );
dbox_setfield( env->status_box, Top_Info_Field, last_top_info_field );
set_top_info_field( env, action_prompt[ env->operation ] );
}
}
else
......@@ -1613,7 +1764,7 @@ static os_error *Do_Next_File( action_environment *env )
*/
switch_buttons( env, &ok_button );
dbox_setfield( env->status_box, Top_Info_Field, msgs_lookup( "85" ));
set_top_info_field( env, "85" );
set_bottom_info_field( env, env->selection_summary );
}
else if ( ( env->operation == Action_Deleting ||
......@@ -1626,8 +1777,9 @@ static os_error *Do_Next_File( action_environment *env )
sprintf( top_field, msgs_lookup( "86" ), env->locked_not_deleted );
dbox_setfield( env->status_box, Top_Info_Field, top_field );
set_bottom_info_field( env, env->selection_summary );
set_top_info_field( env, "85" );
set_bottom_info_field( env, top_field);
}
else
{
......@@ -1642,10 +1794,11 @@ static os_error *Do_Next_File( action_environment *env )
return NULL;
}
static os_error *Do_Test_Add_To_Read_List( action_environment *env )
{
os_error *err;
int should_be_added;
BOOL should_be_added;
err = test_add_to_read_list( env, &should_be_added );
......@@ -1662,8 +1815,7 @@ static os_error *Do_Test_Add_To_Read_List( action_environment *env )
if ( env->confirm )
{
switch_buttons( env, &confirm_buttons );
last_top_info_field = msgs_lookup( action_prompt[ env->operation ] );
dbox_setfield( env->status_box, Top_Info_Field, last_top_info_field );
set_top_info_field( env, action_prompt[ env->operation ] );
}
}
else
......@@ -1676,7 +1828,7 @@ static os_error *Do_Test_Add_To_Read_List( action_environment *env )
static os_error *Do_Add_To_Read_List( action_environment *env )
{
int i_am_full;
BOOL i_am_full;
add_to_read_list( env, &i_am_full );
......@@ -1689,15 +1841,20 @@ static os_error *Do_Add_To_Read_List( action_environment *env )
static os_error *Do_Check_Full_Reading( action_environment *env )
{
os_error *err;
int i_am_full;
int need_another_file;
int that_finished_a_file;
BOOL i_am_full;
BOOL need_another_file;
BOOL that_finished_a_file;
uint32_t p = 0;
err = read_a_block( &i_am_full, &need_another_file, &that_finished_a_file );
err = read_a_block( &i_am_full, &need_another_file, &that_finished_a_file, &p );
if ( err )
return err;
#ifdef USE_PROGRESS_BAR
add_progress(env, p, "Block read");
#endif
if ( i_am_full )
{
switch_to_writing( env );
......@@ -1730,26 +1887,33 @@ static os_error *Do_Check_Full_Reading( action_environment *env )
return NULL;
}
static os_error *Do_Check_Empty_Writing( action_environment *env )
{
os_error *err;
int i_am_empty;
int that_finished_a_file;
BOOL i_am_empty;
BOOL that_finished_a_file;
uint32_t p = 0;
err = write_a_block( &i_am_empty, &that_finished_a_file );
err = write_a_block( &i_am_empty, &that_finished_a_file, &p );
if ( err )
return err;
#ifdef USE_PROGRESS_BAR
add_progress(env, p, "Block write");
#endif
if ( i_am_empty )
{
switch_to_reading( env );
}
else if ( that_finished_a_file )
{
if ( env->operation != Action_CopyMoving )
{
if ( size_of_finished_file >= 0 )
if ( finished_obj_was_file )
{
more_bottom_progress( env, 1 );
}
......@@ -1774,6 +1938,7 @@ static os_error *Do_Check_Empty_Writing( action_environment *env )
return NULL;
}
static os_error *Do_Attempt_Rename( action_environment *env, int which_one )
{
os_error *err;
......@@ -1814,11 +1979,15 @@ static os_error *Do_Attempt_Rename( action_environment *env, int which_one )
{
env->action = Attempt_Relock;
}
#ifdef USE_PROGRESS_BAR
add_progress(env, progress_of_next_node(env->test_search), "Do_Attempt_Rename");
#endif
}
return err;
}
static os_error *Do_Attempt_Unlock( action_environment *env )
{
os_error *err;
......@@ -1832,7 +2001,7 @@ static os_error *Do_Attempt_Unlock( action_environment *env )
/*
Ignore error as don't care if it fails
*/
(void)set_access_to_file( filename, attributes_of_next_node( env->test_search ) & ~Attribute_Locked );
(void)set_access_to_file( filename, attributes_of_next_node( env->test_search ) & ~locked_attribute );
overflowing_free( filename );
......@@ -1841,6 +2010,7 @@ static os_error *Do_Attempt_Unlock( action_environment *env )
return NULL;
}
/*
Relock destination of rename after unlocking source
*/
......@@ -1876,7 +2046,8 @@ static os_error *Do_Attempt_Relock( action_environment *env )
return NULL;
}
static os_error *Do_Convert_To_CopyMove( action_environment *env, int after_unlock )
static os_error *Do_Convert_To_CopyMove( action_environment *env, BOOL after_unlock )
{
os_error *err;
char *filename;
......@@ -1909,6 +2080,15 @@ static os_error *Do_Convert_To_CopyMove( action_environment *env, int after_unlo
return_directories_last( env->test_search, Yes );
recurse_search_context( env->test_search, Yes );
/*
Reset the progress bar as the operation is restarted as a copymove
*/
#ifdef USE_PROGRESS_BAR
debugact(( "changed operation: %s\n", debug_operation( env->operation ) ));
listfiles_convert_to_copymove( env->test_search );
env->progress = 0;
#endif
err = selection_summary( env->test_search, &env->selection_summary );
env->locked_not_deleted = 0;
......@@ -1916,25 +2096,28 @@ static os_error *Do_Convert_To_CopyMove( action_environment *env, int after_unlo
return err;
}
static os_error *Do_Attempt_Delete( action_environment *env )
{
os_error *err;
char *filename;
int inhibit_progress = No;
BOOL inhibit_progress = No;
int prev_access;
uint32_t p = 0;
if ( env->operation != Action_CopyMoving )
{
wimpt_noerr( next_nodename( env->test_search, &filename ));
#ifdef USE_PROGRESS_BAR
p = progress_of_next_node(env->test_search);
#endif
}
else
{
filename = source_of_finished_file;
filename = finished_obj_source_name;
}
#ifdef debugact
dprintf("Do_Attempt_Delete: filename = %s\n",filename);
#endif
debugact(( "Do_Attempt_Delete: filename = %s p = %08x\n", filename, p ));
/*
JRS 29/1/92 1st attempt to delete the node without touching the access.
......@@ -1955,7 +2138,7 @@ dprintf("Do_Attempt_Delete: filename = %s\n",filename);
err = get_access_to_file(filename, &prev_access);
if ( err ) prev_access = -1;
err = set_access_to_file(filename, prev_access & ~Attribute_Locked);
err = set_access_to_file(filename, prev_access & ~locked_attribute);
if ( err && (err->errnum & FileError_Mask) != ErrorNumber_NotFound )
return err;
......@@ -1974,7 +2157,8 @@ dprintf("Do_Attempt_Delete: filename = %s\n",filename);
{
/* JRS 28/1/92 test if access should be restored */
if ( prev_access != -1 )
{ /*
{
/*
Put the access back to where it was
*/
set_access_to_file( filename, prev_access);
......@@ -2038,6 +2222,13 @@ dprintf("Do_Attempt_Delete: filename = %s\n",filename);
if ( err )
return err;
/*
Only update progress bar if the file was actually deleted
*/
#ifdef USE_PROGRESS_BAR
add_progress(env, p, "Do_Attempt_Delete");
#endif
if ( env->operation != Action_CopyMoving )
{
if ( !inhibit_progress )
......@@ -2045,7 +2236,7 @@ dprintf("Do_Attempt_Delete: filename = %s\n",filename);
/*
Keep the user informed of what's happening
*/
if ( objecttype_of_next_node( env->test_search ) != ObjectType_File )
if ( objecttype_of_next_node( env->test_search ) != object_file )
{
more_top_progress( env, 1 );
}
......@@ -2062,7 +2253,7 @@ dprintf("Do_Attempt_Delete: filename = %s\n",filename);
/*
Update progress if it's a file we've just finished moving
*/
if ( size_of_finished_file >= 0 )
if ( finished_obj_was_file )
{
more_bottom_progress( env, 1 );
}
......@@ -2075,11 +2266,12 @@ dprintf("Do_Attempt_Delete: filename = %s\n",filename);
return NULL;
}
static os_error *Do_Attempt_Set_Access( action_environment *env )
{
os_error *err;
if ( objecttype_of_next_node( env->test_search ) != ObjectType_File )
if ( objecttype_of_next_node( env->test_search ) != object_file )
{
err =
set_access(
......@@ -2107,18 +2299,23 @@ static os_error *Do_Attempt_Set_Access( action_environment *env )
more_bottom_progress( env, 1 );
}
#ifdef USE_PROGRESS_BAR
add_progress(env, progress_of_next_node(env->test_search), "Do_Attempt_Set_Access");
#endif
env->action = Next_File;
return NULL;
}
static os_error *Do_Attempt_Set_Type( action_environment *env )
{
os_error *err;
char *filename;
os_filestr fileplace;
if ( objecttype_of_next_node( env->test_search ) == ObjectType_Directory )
if ( objecttype_of_next_node( env->test_search ) == object_directory )
{
more_top_progress( env, 1 );
}
......@@ -2130,7 +2327,7 @@ static os_error *Do_Attempt_Set_Type( action_environment *env )
if ( err )
return err;
fileplace.action = 0x12; /* set file type */
fileplace.action = OSFile_SetType;
fileplace.name = filename;
fileplace.loadaddr = env->new_type;
......@@ -2145,17 +2342,26 @@ static os_error *Do_Attempt_Set_Type( action_environment *env )
}
#ifdef USE_PROGRESS_BAR
add_progress(env, progress_of_next_node(env->test_search), "Do_Attempt_Set_Type");
#endif
env->action = Next_File;
return NULL;
}
static os_error *Do_Attempt_Stamp( action_environment *env )
{
os_error *err;
err = stamp( env );
#ifdef USE_PROGRESS_BAR
add_progress(env, progress_of_next_node(env->test_search), "Do_Attempt_Stamp");
#endif
/*
Filter out F. S. Error 46 as this is the error generated by file
servers which can't stamp directories
......@@ -2165,7 +2371,7 @@ static os_error *Do_Attempt_Stamp( action_environment *env )
err = NULL;
if ( objecttype_of_next_node( env->test_search ) == ObjectType_File )
if ( objecttype_of_next_node( env->test_search ) == object_file )
more_bottom_progress( env, 1 );
else
more_top_progress( env, 1 );
......@@ -2175,14 +2381,14 @@ static os_error *Do_Attempt_Stamp( action_environment *env )
return NULL;
}
/*
--- Activity processor for null events ---
*/
static void null_event_activity( action_environment *env )
{
os_error *err = NULL;
char info_buffer[ Info_Field_Length + 15 ];
int end_time;
clock_t end_time;
end_time = clock() + doings_time;
hide_faster_stuff( env );
......@@ -2198,16 +2404,16 @@ static void null_event_activity( action_environment *env )
{
if ( env->in_error )
{
#ifdef REDERROR
#ifdef USE_RED_ERROR
wimp_set_icon_state( dbox_syshandle( env->status_box ), Top_Info_Field, 0xc000000, 0 );
wimp_set_icon_state( dbox_syshandle( env->status_box ), Bottom_Info_Field, 0xc000000, 0 );
#endif
#endif
env->in_error = No;
switch_box_from_error( env );
}
dbox_setfield( env->status_box, Top_Info_Field, env->current_info );
last_top_info_field = env->current_info;
set_top_info_field_raw( env, env->current_info );
}
switch( env->action )
......@@ -2276,16 +2482,49 @@ static void null_event_activity( action_environment *env )
break;
}
}
/*
While there is not error and
we havn't run out of time and
we are accepting NULL events
*/
while ( !err &&
} while ( !err &&
clock() < end_time &&
( event_getmask() & wimp_EMNULL ) == 0 );
#ifdef USE_PROGRESS_BAR
update_progress_bar(env);
#endif
/*
Update the various fields in the dialogue box, if the flags are set
*/
if (UpdatePath)
{
UpdatePath = 0;
dbox_setfield( env->status_box, Bottom_Info_Path, PathString );
}
if (UpdateTop)
{
UpdateTop = 0;
if ( !env->faster || show_when_faster[ env->operation ][ 0 ] )
{
dbox_setlongnumeric( env->status_box, Top_Progress_Field, env->top_progress );
}
}
if (UpdateBottom)
{
UpdateBottom = 0;
if ( !env->faster || show_when_faster[ env->operation ][ 1 ] )
{
dbox_setlongnumeric( env->status_box, Bottom_Progress_Field, env->bottom_progress);
}
}
if ( err )
{
if ( err->errnum == 0 )
......@@ -2326,9 +2565,7 @@ static void null_event_activity( action_environment *env )
*/
if ( ( err->errnum & FileError_Mask ) == ErrorNumber_DiscFull )
{
strcpy(info_buffer, "87a");
strcat(info_buffer, env->current_info_token);
sprintf(info_buffer, msgs_lookup(info_buffer), tolower(env->current_info[0]), &env->current_info[1]);
set_top_info_field_with_current_info(env, "87a", "87");
if ( env->disc_full_already )
{
......@@ -2345,28 +2582,24 @@ static void null_event_activity( action_environment *env )
}
else
{
strcpy(info_buffer, "88a");
strcat(info_buffer, env->current_info_token);
sprintf(info_buffer, msgs_lookup(info_buffer), tolower(env->current_info[0]), &env->current_info[1]);
set_top_info_field_with_current_info(env, "88a", "88");
switch_box_to_error( env, err );
}
dbox_setfield( env->status_box, Top_Info_Field, info_buffer );
last_top_info_field = info_buffer;
/*
Set the info field text to red (assuming it was black)
*/
env->in_error = Yes;
#ifdef REDERROR
#ifdef USE_RED_ERROR
wimp_set_icon_state( dbox_syshandle( env->status_box ), Top_Info_Field, 0xc000000, 0 );
wimp_set_icon_state( dbox_syshandle( env->status_box ), Bottom_Info_Field, 0xc000000, 0 );
#endif
#endif
}
}
}
/*
--- NULL event handler for status box. ---
*/
......@@ -2374,7 +2607,7 @@ BOOL idle_event_handler(dbox db, void *event, void *handle)
{
BOOL handled = No;
db = db; /* keep the compiler quiet */
IGNORE(db);
switch( ((wimp_eventstr *)event)->e )
{
......@@ -2417,6 +2650,7 @@ BOOL idle_event_handler(dbox db, void *event, void *handle)
return handled;
}
/* Fixed stack size !!!
* 3.5k is the max required.
* 2k is a bodge safety factor.
......
......@@ -15,7 +15,7 @@
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdint.h>
#include <locale.h>
#include "dbox.h"
......@@ -23,10 +23,8 @@
#include "Options.h"
#include "dboxlong.h"
#ifdef USE_LONG_LONG
#ifdef USE_COMMAS
static void cvtlong(char *out, uintmax_t num)
static void cvtlong(char *out, uint64_t num)
{
struct lconv *l = localeconv();
char buffer[128];
......@@ -64,7 +62,7 @@ static void cvtlong(char *out, uintmax_t num)
#define cvtlong(buf, n) snprintf(buf, "%ju", n)
#endif
void dbox_setlongnumeric(dbox d, dbox_field f, uintmax_t n)
void dbox_setlongnumeric(dbox d, dbox_field f, uint64_t n)
{
char buf[128];
......@@ -72,5 +70,3 @@ void dbox_setlongnumeric(dbox d, dbox_field f, uintmax_t n)
dbox_setfield(d, f, buf);
}
#endif
......@@ -31,37 +31,46 @@ Revision History:
*/
#if 0
#define debuglist
#define debuglist(k) dprintf k
#else
#define debuglist(k) /* Disabled */
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "Interface/HighFSI.h"
#ifndef __os_h
#include "os.h"
#endif
#include "Options.h"
#include "malloc+.h"
#include "listfiles.h"
#include "allerrs.h"
#include "debug.h"
#include "memmanage.h"
#define Yes 1
#define No 0
#define Yes (!No)
#define Directory_Buffer_Size 20
#define Temp_DirBuffer_Size 640
#define Directory_File_Type 2
typedef struct
{
int load_address;
int execution_address;
int length;
uint32_t length;
int attributes;
int object_type;
char *object_name;
#ifdef USE_PROGRESS_BAR
void *chain_ref;
#endif
} directory_buffer_entry;
typedef struct Search_Nest_Level
......@@ -71,6 +80,14 @@ typedef struct Search_Nest_Level
int entries_in_buffer;
int next_entry_to_return;
directory_buffer_entry directory_buffer[ Directory_Buffer_Size ];
#ifdef USE_PROGRESS_BAR
BOOL counted;
uint32_t total_entries;
int total_progress;
int progress_per_object;
#endif
} search_nest_level;
typedef struct File_Selection
......@@ -97,17 +114,73 @@ typedef struct search_context
file_selection *selection;
file_selection **last_selections_link;
next_leaf_state action;
unsigned int selections_size;
unsigned int selections_reload;
unsigned int selections_execute;
unsigned int selections_attributes;
unsigned int selections_objecttype;
unsigned int recursive:1;
unsigned int directories_first:1;
unsigned int directories_last:1;
unsigned int partitions_as_directories:1;
uint32_t selections_size;
int selections_loadaddr;
int selections_execaddr;
int selections_attributes;
int selections_objecttype;
int recursive:1;
int directories_first:1;
int directories_last:1;
int partitions_as_directories:1;
#ifdef USE_PROGRESS_BAR
uint32_t total_entries;
int total_progress;
int progress_per_object;
void *chain_ref;
#endif
} search_context;
#ifdef USE_PROGRESS_BAR
static uint32_t count_objects_in_dir( char *dir )
{
os_error *err;
os_gbpbstr request;
char buff[Temp_DirBuffer_Size];
int context = 0, c, num = 0;
uint32_t total = 0;
while (context != -1)
{
request.action = OSGBPB_ReadDirEntries;
request.file_handle = (int)dir;
request.data_addr = buff;
request.number = 256;
request.seq_point = context;
request.buf_len = Temp_DirBuffer_Size;
request.wild_fld = 0;
err = os_gbpb( &request );
num = request.number;
c = request.seq_point;
if (err == NULL)
{
if (c == context)
{
/*
Broken archives cause context to never be updated ... not sure why
the SWI does not return an error.
*/
debuglist(( "count_objects_in_dir: aborting\n" ));
return 0;
}
context = c;
total += num;
}
else
{
debuglist(( "count_objects_in_dir: %s\n", e->errmess ));
return 0;
}
}
return total;
}
#endif
/*
This initialises an empty search context.
The search will return a list of files or directories, which must
......@@ -131,6 +204,13 @@ os_error *create_search_context( search_handle *handle )
new_context->partitions_as_directories = Yes;
new_context->action = Process_Node;
#ifdef USE_PROGRESS_BAR
new_context->total_entries = 0;
new_context->total_progress = INT32_MAX;
new_context->progress_per_object = 0;
new_context->chain_ref = NULL;
#endif
return NULL;
}
else
......@@ -142,8 +222,8 @@ os_error *create_search_context( search_handle *handle )
static int is_a_directory( search_handle handle, int objecttype )
{
if ( objecttype == ObjectType_Directory ||
(objecttype == (ObjectType_Directory | ObjectType_File) &&
if ( objecttype == object_directory ||
(objecttype == (object_directory | object_file) &&
handle->partitions_as_directories) )
{
return Yes;
......@@ -157,7 +237,7 @@ static int is_a_directory( search_handle handle, int objecttype )
/*
Sets whether the search is recursive or not
*/
extern void recurse_search_context( search_handle handle, int recursive )
void recurse_search_context( search_handle handle, BOOL recursive )
{
/*
Make sure when changing to recursive that the children of this
......@@ -178,7 +258,7 @@ extern void recurse_search_context( search_handle handle, int recursive )
Sets whether directories should be returned before their contents.
This is relevant only when recursing.
*/
extern void return_directories_first( search_handle handle, int directories_first )
void return_directories_first( search_handle handle, BOOL directories_first )
{
((search_context *)handle)->directories_first = directories_first != No;
}
......@@ -187,7 +267,7 @@ extern void return_directories_first( search_handle handle, int directories_firs
Sets whether directories should be returned after their contents.
This is relevant only when recursing.
*/
extern void return_directories_last( search_handle handle, int directories_last )
void return_directories_last( search_handle handle, BOOL directories_last )
{
handle->directories_last = directories_last != No;
}
......@@ -196,7 +276,7 @@ extern void return_directories_last( search_handle handle, int directories_last
Sets whether partitions should be treated the same as directories or not.
This is relevant only when recursing.
*/
extern void treat_partitions_as_directories( search_handle handle, int partitions_are_directories )
void treat_partitions_as_directories( search_handle handle, BOOL partitions_are_directories )
{
handle->partitions_as_directories = partitions_are_directories;
}
......@@ -292,6 +372,12 @@ os_error *add_selection( search_handle handle, char *file_name, int wordlen )
context->last_selections_link = &new_selection->next_file;
new_selection->next_file = NULL;
debuglist(( "context: %x new selection: %s\n", context, new_selection->selection_name ));
#ifdef USE_PROGRESS_BAR
context->total_entries++;
context->progress_per_object = context->total_progress / context->total_entries;
#endif
return NULL;
}
else
......@@ -454,7 +540,7 @@ os_error *selection_summary( search_handle handle, char **summary )
if ( context->selection == NULL )
{
cont = msgs_lookup("93");
cont = msgs_lookup("93"); /* 'nothing' */
}
else if ( context->selection->next_file == NULL )
{
......@@ -462,7 +548,7 @@ os_error *selection_summary( search_handle handle, char **summary )
}
else
{
cont = msgs_lookup("92");
cont = msgs_lookup("92"); /* 'many' */
}
*summary = overflowing_malloc( strlen( context->directory ) + 1 + strlen( cont ) + 1 );
......@@ -594,7 +680,7 @@ void read_next_node_parameters( search_handle handle )
if ( err )
return;
fileplace.action = 5; /* read catalogue information */
fileplace.action = OSFile_ReadInfo;
fileplace.name = filename;
err = os_file( &fileplace );
......@@ -603,18 +689,23 @@ void read_next_node_parameters( search_handle handle )
return;
handle->selections_size = fileplace.start;
handle->selections_reload = fileplace.loadaddr;
handle->selections_execute = fileplace.execaddr;
handle->selections_loadaddr = fileplace.loadaddr;
handle->selections_execaddr = fileplace.execaddr;
handle->selections_attributes = fileplace.end;
}
typedef enum { the_size, the_load_address, the_execute_address, the_attributes, the_type, the_name } which_thing;
typedef enum {
the_size, the_load_address, the_execute_address, the_attributes, the_type, the_name
#ifdef USE_PROGRESS_BAR
, the_progress, the_ref_ptr
#endif
} which_thing;
/*
Returns one of the values associated with the next node.
If the node doesn't exist the value not_found is returned.
*/
static unsigned int thing_of_next_node( search_handle handle, which_thing thing, int not_found )
static int thing_of_next_node( search_handle handle, which_thing thing, int not_found )
{
search_context *context = (search_context *)handle;
search_nest_level *nf;
......@@ -626,65 +717,107 @@ static unsigned int thing_of_next_node( search_handle handle, which_thing thing,
switch( thing )
{
case the_size:
return context->selections_size;
return (int) context->selections_size;
case the_load_address:
return context->selections_reload;
return context->selections_loadaddr;
case the_execute_address:
return context->selections_execute;
return context->selections_execaddr;
case the_attributes:
return context->selections_attributes;
case the_type:
return context->selections_objecttype;
case the_name:
return (int)context->selection->selection_name;
return (int) context->selection->selection_name;
#ifdef USE_PROGRESS_BAR
case the_progress:
if (context->selections_objecttype == object_directory)
{
debuglist(( "ponn: selection: %08x\n", 0 ));
return 0;
}
else
{
debuglist(( "ponn: selection: %08x\n", context->progress_per_object ));
return context->progress_per_object;
}
case the_ref_ptr:
return (int) &context->chain_ref;
#endif
} /* end switch */
}
else
{
directory_buffer_entry *d;
d = nf->directory_buffer + nf->next_entry_to_return;
switch( thing )
{
case the_size:
return nf->directory_buffer[ nf->next_entry_to_return ].length;
return (int) d->length;
case the_load_address:
return nf->directory_buffer[ nf->next_entry_to_return ].load_address;
return d->load_address;
case the_execute_address:
return nf->directory_buffer[ nf->next_entry_to_return ].execution_address;
return d->execution_address;
case the_attributes:
return nf->directory_buffer[ nf->next_entry_to_return ].attributes;
return d->attributes;
case the_type:
return nf->directory_buffer[ nf->next_entry_to_return ].object_type;
return d->object_type;
case the_name:
return (int)nf->directory_buffer[ nf->next_entry_to_return ].object_name;
return (int) d->object_name;
#ifdef USE_PROGRESS_BAR
case the_progress:
if (d->object_type == object_directory)
{
debuglist(( "ponn: nested: %08x\n", 0 ));
return 0;
}
else
{
debuglist(( "ponn: nested: %08x\n", nf->progress_per_object ));
return nf->progress_per_object;
}
case the_ref_ptr:
return (int) &d->chain_ref;
#endif
}
}
}
debuglist(( "tonn: not found\n" ));
return not_found;
}
unsigned int size_of_next_node( search_handle handle )
uint32_t size_of_next_node( search_handle handle )
{
return thing_of_next_node( handle, the_size, -1 );
return (uint32_t)thing_of_next_node( handle, the_size, 0 );
}
unsigned int reload_of_next_node( search_handle handle )
int reload_of_next_node( search_handle handle )
{
return thing_of_next_node( handle, the_load_address, -1 );
}
unsigned int execute_of_next_node( search_handle handle )
int execute_of_next_node( search_handle handle )
{
return thing_of_next_node( handle, the_execute_address, -1 );
}
unsigned int attributes_of_next_node( search_handle handle )
int attributes_of_next_node( search_handle handle )
{
return thing_of_next_node( handle, the_attributes, -1 );
}
unsigned int objecttype_of_next_node( search_handle handle )
int objecttype_of_next_node( search_handle handle )
{
return thing_of_next_node( handle, the_type, ObjectType_NotFound );
return thing_of_next_node( handle, the_type, object_nothing );
}
char *name_of_next_node( search_handle handle )
......@@ -692,11 +825,24 @@ char *name_of_next_node( search_handle handle )
return (char *)thing_of_next_node( handle, the_name, NULL );
}
#ifdef USE_PROGRESS_BAR
uint32_t progress_of_next_node( search_handle handle )
{
return (uint32_t)thing_of_next_node( handle, the_progress, 0 );
}
void **chain_ref_ptr_of_next_node( search_handle handle )
{
return (void **)thing_of_next_node( handle, the_ref_ptr, NULL );
}
#endif
/*
Assuming a directory has just been found, return whether this return
of this directory was before or after its contents.
*/
unsigned int directory_is_after_contents( search_handle handle )
BOOL directory_is_after_contents( search_handle handle )
{
search_context *context = (search_context *)handle;
......@@ -707,7 +853,7 @@ unsigned int directory_is_after_contents( search_handle handle )
Returns 0 if no more nodes
Returns non-0 if more nodes
*/
unsigned int another_node( search_handle handle )
BOOL another_node( search_handle handle )
{
return ((search_context *)handle)->selection != NULL;
}
......@@ -751,7 +897,7 @@ void skip_list_file( search_handle handle )
context->action = Next_Leaf;
}
os_error *step_to_next_node( search_handle handle )
os_error *step_to_next_node( search_handle handle, uint32_t *progress )
{
search_context *context = (search_context *)handle;
search_nest_level *temp_context;
......@@ -760,11 +906,13 @@ os_error *step_to_next_node( search_handle handle )
char temp_directory_buffer[ Temp_DirBuffer_Size ];
int i;
int pos;
int resolved = No;
BOOL resolved = No;
os_error *err = NULL;
file_selection *next_selection;
int objecttype;
debuglist(( "\nstep_to_next_node\n" ));
/*
While the answer hasn't resolved itself and there's no error
then try the next step of resolving the answer
......@@ -777,6 +925,7 @@ os_error *step_to_next_node( search_handle handle )
/*
Step to the next leaf at this nesting level
*/
debuglist(( "Next_Leaf " ));
if ( context->nested_filenames == NULL )
{
/*
......@@ -786,6 +935,8 @@ os_error *step_to_next_node( search_handle handle )
free_selection( context->selection );
context->selection = next_selection;
debuglist(( "get next selection" ));
context->action = Process_Node;
}
else
......@@ -800,6 +951,7 @@ os_error *step_to_next_node( search_handle handle )
/*
We've run out of cached entries
*/
debuglist(( "cache empty " ));
context->action = Read_Next_Cache_Full;
}
else
......@@ -808,6 +960,7 @@ os_error *step_to_next_node( search_handle handle )
Found an entry in the cache, so let's
process it
*/
debuglist(( "cache ok " ));
context->action = Process_Node;
}
}
......@@ -817,12 +970,14 @@ os_error *step_to_next_node( search_handle handle )
/*
Process the node as supplied by Next_Leaf
*/
debuglist(( "Process_Node " ));
if ( context->selection == NULL )
{
/*
No more entries in the selection, so we've
resolved what happens next
*/
debuglist(( "resolved all " ));
resolved = Yes;
}
else
......@@ -830,31 +985,38 @@ os_error *step_to_next_node( search_handle handle )
/*
Get type of node if needed
*/
debuglist(( "%s ", name_of_next_node( context ) ));
if ( context->nested_filenames == NULL )
{
fileplace.action = 17;
fileplace.action = OSFile_ReadNoPath;
err = next_filename( context, context->nested_filenames, &fileplace.name );
debuglist(( "%s ", fileplace.name ));
if ( err )
{
debuglist(( "err\n" ));
continue;
}
err = os_file( &fileplace );
if ( err )
{
overflowing_free( fileplace.name );
debuglist(( " error\n" ));
continue;
}
/*
Didn't find a selection - generate an error.
*/
if ( fileplace.action == ObjectType_NotFound )
if ( fileplace.action == object_nothing )
{
fileplace.loadaddr = fileplace.action;
fileplace.action = 19;
fileplace.action = OSFile_MakeError;
err = os_file( &fileplace );
overflowing_free( fileplace.name );
debuglist(( " not found\n" ));
continue;
}
......@@ -862,19 +1024,20 @@ os_error *step_to_next_node( search_handle handle )
context->selections_objecttype = fileplace.action;
context->selections_size = fileplace.start;
context->selections_reload = fileplace.loadaddr;
context->selections_execute = fileplace.execaddr;
context->selections_loadaddr = fileplace.loadaddr;
context->selections_execaddr = fileplace.execaddr;
context->selections_attributes = fileplace.end;
}
} /* end if (nested_filenames == NULL) */
objecttype = objecttype_of_next_node( (search_handle)context );
if ( objecttype == ObjectType_NotFound )
if ( objecttype == object_nothing )
{
/*
Didn't find that, so go around
for another time - nothing to do here
*/
debuglist(( "not found " ));
context->action = Next_Leaf;
}
......@@ -885,6 +1048,7 @@ os_error *step_to_next_node( search_handle handle )
If we are returning directories first, then
we have resolved it at this level
*/
debuglist(( "directory " ));
resolved = context->directories_first;
context->action = Nest_Into_Directory;
......@@ -898,8 +1062,9 @@ os_error *step_to_next_node( search_handle handle )
so we've resolved things.
*/
resolved = Yes;
context->action = Next_Leaf;
debuglist(( "resolved " ));
}
}
break;
......@@ -908,8 +1073,25 @@ os_error *step_to_next_node( search_handle handle )
/*
If run out of entries in this directory
*/
debuglist(( "Read_Next_Cache_Full " ));
if ( context->nested_filenames->offset_to_next_item == -1 )
{
#ifdef USE_PROGRESS_BAR
search_nest_level *nf = context->nested_filenames;
int p = 0;
/*
Compensate for rounding errors by adding the 'spare' progress
Isn't totally accurate if copying, as the actual progress values
used will have been halved.
*/
p = nf->total_progress - (nf->total_entries * nf->progress_per_object);
if (p > 0) *progress += (uint32_t)p;
debuglist(( "finished %d entries (total %08x) extra progress +%08x", nf->total_entries, nf->total_progress, p ));
#else
IGNORE(progress);
#endif
/*
Down down one level
*/
......@@ -931,17 +1113,69 @@ os_error *step_to_next_node( search_handle handle )
else
{
char **filename_store;
search_nest_level *nf = context->nested_filenames;
/*
Read more of this directory
*/
gbpbplace.action = 10;
gbpbplace.action = OSGBPB_ReadDirEntriesInfo;
err = next_filename( context, context->nested_filenames->next_search_nest_level, (char **)&gbpbplace.file_handle );
err = next_filename( context, nf->next_search_nest_level, (char **)&gbpbplace.file_handle );
if ( err )
continue;
debuglist(( "%s ", (char *)gbpbplace.file_handle ));
#ifdef USE_PROGRESS_BAR
if (!nf->counted)
{
nf->total_entries = count_objects_in_dir( (char *)gbpbplace.file_handle );
nf->counted = Yes;
if (nf->total_entries != 0)
{
nf->progress_per_object = nf->total_progress / nf->total_entries;
}
else
{
void *ref;
/*
Modify progress values so that half the progress for the dir is
added when the dir is finished (in the rounding process above)
and the other half when written. We have to do this now as when
the dir was added to the chain, we didn't know it was empty.
Of course if the dir is not in the chain, we are not copying, and
so we add all the progress for this dir at once.
*/
if (nf->next_search_nest_level == NULL)
{
/* top level */
ref = context->chain_ref;
}
else
{
int i = nf->next_search_nest_level->next_entry_to_return;
ref = nf->next_search_nest_level->directory_buffer[i].chain_ref;
}
if (ref != NULL)
{
nf->total_progress /= 2;
nf->progress_per_object = 0;
modify_chain_file_progress(ref, nf->total_progress);
}
} /* end if (total_entries > 0) */
debuglist(( "%d entries %08x total progress %08x per object ", nf->total_entries, nf->total_progress, nf->progress_per_object ));
} /* end if (!counted) */
#endif
gbpbplace.data_addr = &temp_directory_buffer;
gbpbplace.number = Directory_Buffer_Size;
gbpbplace.seq_point = context->nested_filenames->offset_to_next_item;
......@@ -985,15 +1219,15 @@ os_error *step_to_next_node( search_handle handle )
for ( i = 0, pos = 0; i < gbpbplace.number; i++ )
{
context->nested_filenames->directory_buffer[ i ].load_address = *(int *)&temp_directory_buffer[ pos ];
pos += 4;
pos += sizeof(int);
context->nested_filenames->directory_buffer[ i ].execution_address = *(int *)&temp_directory_buffer[ pos ];
pos += 4;
context->nested_filenames->directory_buffer[ i ].length = *(int *)&temp_directory_buffer[ pos ];
pos += 4;
pos += sizeof(int);
context->nested_filenames->directory_buffer[ i ].length = *(uint32_t *)&temp_directory_buffer[ pos ];
pos += sizeof(uint32_t);
context->nested_filenames->directory_buffer[ i ].attributes = *(int *)&temp_directory_buffer[ pos ];
pos += 4;
pos += sizeof(int);
context->nested_filenames->directory_buffer[ i ].object_type = *(int *)&temp_directory_buffer[ pos ];
pos += 4;
pos += sizeof(int);
/*
Free the filename if there's one there
......@@ -1049,6 +1283,7 @@ os_error *step_to_next_node( search_handle handle )
/*
Go down into the next nesting level
*/
debuglist(( "Nest_Into_Directory " ));
temp_context = context->nested_filenames;
......@@ -1065,9 +1300,27 @@ os_error *step_to_next_node( search_handle handle )
context->nested_filenames->entries_in_buffer = 0;
context->nested_filenames->next_entry_to_return = -1;
#ifdef USE_PROGRESS_BAR
if (temp_context != NULL)
{
context->nested_filenames->total_progress = temp_context->progress_per_object;
}
else
{
context->nested_filenames->total_progress = context->progress_per_object;
}
/* Default values, will be overwitten if this object is a dir */
context->nested_filenames->progress_per_object = 0;
context->nested_filenames->total_entries = 0;
context->nested_filenames->counted = No;
#endif
for ( i = 0; i < Directory_Buffer_Size; i++ )
{
context->nested_filenames->directory_buffer[ i ].object_name = NULL;
#ifdef USE_PROGRESS_BAR
context->nested_filenames->directory_buffer[ i ].chain_ref = NULL;
#endif
}
context->action = Next_Leaf;
......@@ -1077,9 +1330,23 @@ os_error *step_to_next_node( search_handle handle )
default: /* disaster!!!!! */
err = error( mb_unexpected_state );
break;
}
}
} /* end switch */
debuglist(( "\n" ));
} /* end while */
return err;
}
#ifdef USE_PROGRESS_BAR
void listfiles_convert_to_copymove( search_handle handle )
{
search_context *context = (search_context *)handle;
if (context == NULL) return;
context->total_progress /= 2;
}
#endif
......@@ -28,7 +28,7 @@ Theory:
(1) read blocks (or all) of source file(s) into a contiguous chunk of store
- extend as necessary up to next slot size
- be prepared to loose information if slot size has to be shrunk
- be prepared to lose information if slot size has to be shrunk
(2) write blocks to destination file(s)
......@@ -64,19 +64,24 @@ Notes:
*/
#if 0
#define debugmem
#define debugmem(k) dprintf k
#else
#define debugmem(k) /* Disabled */
#endif
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include <stdlib.h>
#include "kernel.h"
#include "Interface/HighFSI.h"
#include "os.h"
#include "wimp.h"
#include "Options.h"
#include "chains.h"
#include "allerrs.h"
#include "malloc+.h"
......@@ -84,16 +89,11 @@ Notes:
#include "debug.h"
#if Timing
static int copytime;
static clock_t copytime;
#endif
#define Yes 1
#define No 0
#define ObjectType_NotFound 0
#define ObjectType_File 1
#define ObjectType_Directory 2
#define Yes (!No)
#define InitialBlockSize 4096
#define SmallBlockSize 3072 /* check the transfer rate is not too low if the blocksize reduces below this */
......@@ -127,16 +127,22 @@ typedef struct
int source_file_handle;
char *destination_filename;
int destination_file_handle;
int size;
uint32_t size;
int reload;
int execute;
int attributes;
int objecttype;
int forceit;
int read_to;
int written_to;
BOOL forceit;
uint32_t read_to;
uint32_t written_to;
write_activity write_state;
int start_of_buffer; /* offset into memory */
#ifdef USE_PROGRESS_BAR
uint32_t total_progress;
uint32_t read_progress;
uint32_t write_progress;
#endif
} files_header;
/*
......@@ -145,18 +151,18 @@ typedef struct
static chain_header files_chain; /* All the files registered with memmanage */
static int application_max_size;
static char *buffer_base_address; /* Base of buffer area */
static int buffer_offset; /* offset to add to botom, top, and any other offsets into the area */
static int buffer_offset; /* offset to add to bottom, top, and any other offsets into the area */
/* used when the area contents are shuffled */
static int buffer_bottom; /* offset to 1st used byte in buffer area */
static int buffer_top; /* offset to top free section in buffer area */
static int buffer_end; /* offset to end of buffer area */
static int last_requested_size;
static int src_block_size;
static int dest_block_size;
static int time_quanta = NominalTimeQuanta;
static int minimum_block_size = 512;
int size_of_finished_file;
char *source_of_finished_file;
BOOL finished_obj_was_file;
char *finished_obj_source_name;
/* JRS addition 16/1/92 */
/* accumulate transfer times at initial blocksize to compare timings at smaller
......@@ -170,11 +176,14 @@ char *source_of_finished_file;
#define timing_NAccumulated 4 /* accumulate this many timings to average out variation */
static struct
{
{
int rate; /* transfer rate calculated from accumulator and blocksize */
int accumulator;
int naccumulated;
} timing[2]; /* read and write initial timing */
} timing[2]; /* read and write initial timing */
/*
Rate evaluation functions
*/
static void timing_init(void)
{
......@@ -190,9 +199,8 @@ static void timing_init(void)
static int t__accumulatortorate(int accumulated_time, int blocksize)
{ /* convert an accumulated timing to a transfer rate value */
if (accumulated_time < 1) accumulated_time = 1; /* ensure no div by zero */
#ifdef debugmem
dprintf("calcrate %d,%d->%d\n", accumulated_time, blocksize,(blocksize<<8) / accumulated_time);
#endif
debugmem(( "t__accumulatortorate: %d,%d->%d\n", accumulated_time, blocksize,(blocksize<<8) / accumulated_time));
return (blocksize<<8) / accumulated_time; /* shift is to gain integer value range */
}
......@@ -264,9 +272,7 @@ static int extend_application_slot( int amount )
wimp_slotsize( &currentslot, &nextslot, &freepool );
#ifdef debugmem
dprintf("extend_application_slot: amount = %d, new size = %d\n",amount,currentslot);
#endif
debugmem(( "extend_application_slot: amount = %d, new size = %d\n",amount,currentslot));
return currentslot - oldslot;
}
......@@ -279,7 +285,7 @@ dprintf("extend_application_slot: amount = %d, new size = %d\n",amount,currentsl
/*
Ensure that the top to end amount free is at least size
*/
static int buffer_ensure( int size )
static BOOL buffer_ensure( int size )
{
if ( buffer_end - buffer_top < size )
{
......@@ -296,7 +302,7 @@ static int buffer_ensure( int size )
*/
static int grow_buffer( int *size )
{
int answer = No;
BOOL answer = No;
/*
Upper bound by application_max_size
......@@ -343,26 +349,26 @@ static os_error *close_file( int *handle )
Creates the file to be the given size, dead, with read/write
access only.
*/
static os_error *create_file_dead( char *filename, int size )
static os_error *create_file_dead( char *filename, uint32_t size )
{
os_filestr fileplace;
os_error *err;
fileplace.action = 7; /* create a file */
fileplace.action = OSFile_Create;
fileplace.name = filename;
fileplace.loadaddr = (int) 0xdeaddead;
fileplace.execaddr = (int) 0xdeaddead;
fileplace.start = 0;
fileplace.end = size;
fileplace.end = (int)size;
err = os_file( &fileplace );
if ( err )
return err;
fileplace.action = 4; /* set access to a file */
fileplace.action = OSFile_WriteAttr;
fileplace.name = filename;
fileplace.end = 0x3; /* read/write only */
fileplace.end = read_attribute | write_attribute;
return os_file( &fileplace );
}
......@@ -371,7 +377,7 @@ static os_error *create_directory( char *dirname )
{
os_filestr fileplace;
fileplace.action = 8; /* create a directory */
fileplace.action = OSFile_CreateDir;
fileplace.name = dirname;
fileplace.start = 0;
......@@ -382,7 +388,7 @@ static os_error *write_catalogue_information( char *filename, int reload, int ex
{
os_filestr fileplace;
fileplace.action = 1; /* write catalogue information */
fileplace.action = OSFile_WriteInfo;
fileplace.name = filename;
fileplace.loadaddr = reload;
fileplace.execaddr = execute;
......@@ -395,7 +401,7 @@ static os_error *write_attributes( char *filename, int attributes )
{
os_filestr fileplace;
fileplace.action = 4; /* write attributes */
fileplace.action = OSFile_WriteAttr;
fileplace.name = filename;
fileplace.end = attributes;
......@@ -568,12 +574,13 @@ static void remove_fh( files_header *fh )
if ( fh->source_filename )
overflowing_free( fh->source_filename );
overflowing_free( fh->destination_filename );
overflowing_free( fh );
}
/*
Assumuing no buffer in buffer chain, and no open files, remove
Assuming no buffer in buffer chain, and no open files, remove
forwards file from files_chain.
*/
static void remove_file_from_chain( void )
......@@ -590,22 +597,22 @@ static void remove_file_from_chain( void )
Special indication that it has been a directory that's just
been finished
*/
if ( fh->objecttype == ObjectType_Directory )
if ( fh->objecttype == object_directory )
{
size_of_finished_file = -1;
finished_obj_was_file = No;
}
else
{
size_of_finished_file = fh->size;
finished_obj_was_file = Yes;
}
/*
Record the source filename of the finished file
*/
if ( source_of_finished_file )
overflowing_free( source_of_finished_file );
if ( finished_obj_source_name )
overflowing_free( finished_obj_source_name );
source_of_finished_file = fh->source_filename;
finished_obj_source_name = fh->source_filename;
fh->source_filename = NULL;
remove_fh( fh );
......@@ -623,7 +630,7 @@ static files_header *next_fh_to_read( void )
{
fh = chain_link_Wrapper( link );
if ( fh->objecttype != ObjectType_Directory &&
if ( fh->objecttype != object_directory &&
( fh->read_to < fh->size ||
fh->source_file_handle ) )
{
......@@ -664,9 +671,7 @@ static int grow( int block )
block = (block + (block>>1)) & ~4095;
}
#ifdef debugmem
dprintf( "growing to %d\n", block );
#endif
debugmem(( "grow: to %d\n", block ));
return block;
}
......@@ -689,9 +694,7 @@ static int shrink( int block )
if ( block < minimum_block_size )
block = minimum_block_size;
#ifdef debugmem
dprintf( "shrinking to %d\n", block );
#endif
debugmem(( "shrink: to %d\n", block ));
return block;
}
......@@ -709,7 +712,7 @@ static void truncate_overhanging_files( void )
{
fh = chain_link_Wrapper( link );
if ( fh->objecttype != ObjectType_Directory )
if ( fh->objecttype != object_directory )
{
if ( fh->start_of_buffer >= buffer_top )
{
......@@ -818,9 +821,7 @@ void action_slot( int size )
{
int size_change = size - application_current_size();
#ifdef debugmem
dprintf( "Change slot by %d to %d\n", size_change, size );
#endif
debugmem(( "action_slot: by %d to %d\n", size_change, size ));
if ( size_change > 0 )
{
......@@ -846,9 +847,7 @@ dprintf( "Change slot by %d to %d\n", size_change, size );
/*
Ensure the data is at the bottom of the buffer area
*/
#ifdef debugmem
dprintf( "Base=%#010x, offset=%d, bottom=%d, top=%d, end=%d\n", (int)buffer_base_address, buffer_offset, buffer_bottom, buffer_top, buffer_end );
#endif
debugmem(( "action_slot: Base=%#010x, offset=%d, bottom=%d, top=%d, end=%d\n", (int)buffer_base_address, buffer_offset, buffer_bottom, buffer_top, buffer_end ));
memmove(
buffer_base_address,
buffer_base_address + buffer_bottom + buffer_offset,
......@@ -875,10 +874,8 @@ dprintf( "Base=%#010x, offset=%d, bottom=%d, top=%d, end=%d\n", (int)buffer_base
truncate_overhanging_files();
application_max_size = (int)(buffer_base_address + buffer_offset + buffer_end) - 0x8000;
#ifdef debugmem
dprintf( "Application max size is now %d\n", application_max_size );
dprintf( "Base=%#010x, offset=%d, bottom=%d, top=%d, end=%d\n", (int)buffer_base_address, buffer_offset, buffer_bottom, buffer_top, buffer_end );
#endif
debugmem(( "action_slot: app max size %d\n", application_max_size ));
debugmem(( "action_slot: Base=%#010x, offset=%d, bottom=%d, top=%d, end=%d\n", (int)buffer_base_address, buffer_offset, buffer_bottom, buffer_top, buffer_end ));
}
/*
......@@ -892,7 +889,7 @@ os_error *init_memmanagement( void )
chain_initialise_header( &files_chain );
/*
This determins the maximum size we will allow buffer
This determines the maximum size we will allow buffer
allocation to grow to. This starts at the
current next slot size, then gets adjusted when the
user drags the memory slider
......@@ -908,13 +905,7 @@ os_error *init_memmanagement( void )
buffer_top = 0;
buffer_end = 0;
/*
A cludge to stop memory size dragging from oscillating
about a non-memory block size boundary.
*/
last_requested_size = -1;
source_of_finished_file = NULL;
finished_obj_source_name = NULL;
(void)_kernel_register_slotextend( memmanage_slotextend );
......@@ -981,7 +972,13 @@ void closedown_memmanagement( void )
/*
Add a file to the end of the files chain
*/
os_error *add_file_to_chain( char *destination, char *source, int size, int reload, int execute, int attributes, int objecttype, int forceit, int *i_am_full )
os_error *add_file_to_chain( char *destination, char *source,
uint32_t size, int reload, int execute, int attributes, int objecttype,
BOOL forceit, BOOL *i_am_full
#ifdef USE_PROGRESS_BAR
, uint32_t progress, void **ref
#endif
)
{
files_header *fh;
......@@ -1014,6 +1011,13 @@ os_error *add_file_to_chain( char *destination, char *source, int size, int relo
fh->write_state = write_not_started;
fh->start_of_buffer = 0;
#ifdef USE_PROGRESS_BAR
fh->total_progress = progress / 2;
fh->write_progress = fh->read_progress = fh->total_progress;
if (ref != NULL) *ref = fh;
debugmem(( "add_file_to_chain: %s type %d progress %08x\n", destination, objecttype, fh->total_progress ));
#endif
/*
link to backwards end of files chain
*/
......@@ -1038,14 +1042,31 @@ os_error *add_file_to_chain( char *destination, char *source, int size, int relo
return error( mb_malloc_failed );
}
os_error *read_a_block( int *i_am_full, int *need_another_file, int *that_finished_a_file )
#ifdef USE_PROGRESS_BAR
void modify_chain_file_progress(void *ref, uint32_t progress)
{
files_header *fh = (files_header *)ref;
if (fh != NULL)
{
debugmem(( "\nmodify chain: %s %x\n", fh->destination_filename, progress ));
fh->write_progress = fh->total_progress = progress;
}
}
#endif
/* Modified to return the progress value of the finished file */
os_error *read_a_block( BOOL *i_am_full, BOOL *need_another_file, BOOL *that_finished_a_file, uint32_t *progress )
{
files_header *fh;
os_regset r;
os_error *err;
os_gbpbstr gbpbplace;
int size_needed;
int t;
uint32_t start_read_to;
clock_t t;
*i_am_full = No;
*that_finished_a_file = No;
......@@ -1061,18 +1082,16 @@ os_error *read_a_block( int *i_am_full, int *need_another_file, int *that_finish
*need_another_file = No;
#ifdef debugmem
dprintf( "read_a_block from %s\n", fh->source_filename );
#endif
debugmem(( "read_a_block: from %s\n", fh->source_filename ));
start_read_to = fh->read_to;
/*
If we have to do some reading
*/
if ( fh->read_to < fh->size )
{
#ifdef debugmem
dprintf( "R" );
#endif
debugmem(( "R" ));
/*
Work out how much buffer is needed...
*/
......@@ -1086,6 +1105,7 @@ dprintf( "R" );
}
else
{
/* This calculation fits in a signed integer provided src_block_size < 2G */
size_needed = fh->size - fh->read_to;
}
......@@ -1119,39 +1139,6 @@ dprintf( "R" );
fh->start_of_buffer = buffer_top;
}
#if 0
/* Using OS_GBPB is faster if the file is already open */
/*
If haven't already started on the open-gbpb-close sequence AND
file size fits into buffer allowed
*/
if ( fh->read_to == 0 && fh->size <= size_needed )
{
/*
If were reading by blocks, but now decided its OK to read by whole file
*/
if ( fh->source_file_handle )
close_file( &fh->source_file_handle );
/*
optimal read case: enough ram to read whole file
*/
fileplace.action = 16; /* load file */
fileplace.name = fh->source_filename;
fileplace.loadaddr = (int)(buffer_base_address + buffer_offset + fh->start_of_buffer);
fileplace.execaddr = 0;
err = os_file( &fileplace );
if ( err )
return err;
fh->read_to = fh->size;
buffer_top += fh->size;
}
else
#endif
{
/*
Sub-optimal case: read file in chunks
......@@ -1159,10 +1146,8 @@ dprintf( "R" );
*/
if ( fh->source_file_handle == 0 )
{
#ifdef debugmem
dprintf( "O" );
#endif
r.r[0] = 0x4f;
debugmem(( "O" ));
r.r[0] = open_read | open_nopath | open_nodir | open_mustopen;
r.r[1] = (int)fh->source_filename;
err = os_find( &r );
......@@ -1178,15 +1163,15 @@ dprintf( "O" );
/*
Read a block into the buffer.
*/
gbpbplace.action = 3; /* read bytes from file at position */
gbpbplace.action = OSGBPB_ReadFromGiven;
gbpbplace.file_handle = fh->source_file_handle;
gbpbplace.data_addr = buffer_base_address + buffer_offset + buffer_top;
gbpbplace.number = size_needed;
gbpbplace.seq_point = fh->read_to;
#ifdef debugmem
dprintf( "r(%d,%d<-%d)", gbpbplace.data_addr, gbpbplace.number, gbpbplace.seq_point );
#endif
debugmem(( "read_a_block: buf %x + %u [%u-%u]\n", buffer_base_address, buffer_offset,
buffer_bottom, buffer_top ));
debugmem(( "read_a_block: (%d,%d<-%d)\n", gbpbplace.data_addr, gbpbplace.number, gbpbplace.seq_point ));
err = os_gbpb( &gbpbplace );
if ( err )
......@@ -1210,9 +1195,7 @@ dprintf( "r(%d,%d<-%d)", gbpbplace.data_addr, gbpbplace.number, gbpbplace.seq_po
{ /* if the transfer rate is suffering at this small blocksize,
* increase time_quanta to cause the blocksize to grow */
if (time_quanta < MaxTimeQuanta) time_quanta *= 2;
#ifdef debugmem
dprintf("change time_quanta to %d\n", time_quanta);
#endif
debugmem(( "read_a_block: time_quanta to %d\n", time_quanta));
}
if ( t < time_quanta - TimeQuantaHysteresis) src_block_size = grow( src_block_size );
if ( t > time_quanta + TimeQuantaHysteresis) src_block_size = shrink( src_block_size );
......@@ -1221,15 +1204,12 @@ dprintf("change time_quanta to %d\n", time_quanta);
if ( fh->read_to >= fh->size )
{
#ifdef debugmem
dprintf( "C" );
#endif
debugmem(( "C" ));
err = close_file( &fh->source_file_handle );
if ( err )
return err;
}
}
}
/*
If we've finished reading the file
......@@ -1238,17 +1218,37 @@ dprintf( "C" );
{
*that_finished_a_file = Yes;
#ifdef USE_PROGRESS_BAR
*progress = fh->read_progress;
#else
IGNORE(progress);
#endif
/*
If there isn't another file to read, tell the client about
it now.
*/
if ( next_fh_to_read() == NULL )
*need_another_file = Yes;
#ifdef USE_PROGRESS_BAR
}
else
{
uint64_t p;
uint32_t b;
#ifdef debugmem
dprintf( "X\n" );
#endif
b = fh->read_to - start_read_to; /* bytes read this time */
p = (fh->total_progress * (uint64_t)b) / fh->size;
fh->read_progress -= (uint32_t) p;
*progress = (uint32_t) p;
debugmem(( "partial read: %u bytes / %u = %08x progress\n", b, fh->size, *progress ));
#endif
}
debugmem(( "X\n" ));
return NULL;
}
......@@ -1258,7 +1258,7 @@ void skip_file_read( void )
skip_file( next_fh_to_read() );
}
static os_error *int_write_a_block( int *i_am_empty, int *that_finished_a_file )
static os_error *int_write_a_block( BOOL *i_am_empty, BOOL *that_finished_a_file, uint32_t *progress )
{
os_gbpbstr gbpbplace;
os_filestr fileplace;
......@@ -1266,8 +1266,9 @@ static os_error *int_write_a_block( int *i_am_empty, int *that_finished_a_file )
os_regset r;
os_error *err = NULL;
int amount_to_write;
int t;
static int dont_set_dir_info;
uint32_t start_written_to;
clock_t t;
static BOOL dont_set_dir_info = No;
*i_am_empty = No;
*that_finished_a_file = No;
......@@ -1284,14 +1285,12 @@ static os_error *int_write_a_block( int *i_am_empty, int *that_finished_a_file )
fh = chain_link_Wrapper( files_chain.forwards );
#ifdef debugmem
dprintf( "int_write_a_block to %s\n", fh->destination_filename );
#endif
debugmem(( "int_write_a_block to %s\n", fh->destination_filename ));
/*
no more buffer to write when there's more file to write?
*/
if ( fh->objecttype != ObjectType_Directory &&
if ( fh->objecttype != object_directory &&
fh->read_to - fh->written_to == 0 &&
fh->written_to < fh->size )
{
......@@ -1300,9 +1299,9 @@ dprintf( "int_write_a_block to %s\n", fh->destination_filename );
return NULL;
}
#ifdef debugmem
dprintf( "W" );
#endif
start_written_to = fh->written_to;
debugmem(( "W" ));
/*
amount_to_write is lesser of a dest_block_size and the amount buffered of the file
......@@ -1313,6 +1312,7 @@ dprintf( "W" );
}
else
{
/* This calculation fits in a signed integer provided dest_block_size < 2G */
amount_to_write = fh->read_to - fh->written_to;
}
......@@ -1322,11 +1322,9 @@ dprintf( "W" );
fh->write_state == write_f_tried_cdirs ||
fh->write_state == write_f_tried_both ))
{
if ( fh->objecttype == ObjectType_Directory )
if ( fh->objecttype == object_directory )
{
#ifdef debugmem
dprintf( "D" );
#endif
debugmem(( "D" ));
/*
Start up directory
*/
......@@ -1344,13 +1342,11 @@ dprintf( "D" );
*/
if ( fh->size <= amount_to_write )
{
#ifdef debugmem
dprintf( "S" );
#endif
debugmem(( "S" ));
/*
Optimised case - try save
*/
fileplace.action = 0; /* save file */
fileplace.action = OSFile_Save;
fileplace.name = fh->destination_filename;
fileplace.loadaddr = fh->reload;
fileplace.execaddr = fh->execute;
......@@ -1370,9 +1366,7 @@ dprintf( "S" );
}
else
{
#ifdef debugmem
dprintf( "c" );
#endif
debugmem(( "c" ));
/*
Sub-optimal case - open, GBPB, close
*/
......@@ -1395,9 +1389,9 @@ dprintf( "c" );
/*
We haven't tried unlocking yet - give it a go
*/
fileplace.action = 4; /* set file attributes */
fileplace.action = OSFile_WriteAttr;
fileplace.name = fh->destination_filename;
fileplace.end = 3; /* owner read/write */
fileplace.end = read_attribute | write_attribute;
os_file( &fileplace ); /* ignore any error back */
......@@ -1421,7 +1415,7 @@ dprintf( "c" );
if ( !err )
{
/*
no error - try openning/saveing again, but don't retry cdirs on fail
no error - try opening/saving again, but don't retry cdirs on fail
*/
if ( fh->write_state == write_not_started )
fh->write_state = write_f_tried_cdirs;
......@@ -1434,14 +1428,12 @@ dprintf( "c" );
if ( !err && fh->write_state == write_openit )
{
#ifdef debugmem
dprintf( "O" );
#endif
debugmem(( "O" ));
/*
Open it up. The file has been successfully created if we're here, so
any failures at this point are bad news.
*/
r.r[0] = 0xcf; /* open up and give an error if directory or not exists */
r.r[0] = open_update | open_nopath | open_nodir | open_mustopen;
r.r[1] = (int)fh->destination_filename;
err = os_find( &r );
......@@ -1455,15 +1447,13 @@ dprintf( "O" );
if ( !err && fh->write_state == write_truncateopen )
{
#ifdef debugmem
dprintf( "T" );
#endif
debugmem(( "T" ));
/*
Once the file's open set its extent to 0. This
prevents FileSwitch loading before update on
blocks of the file.
*/
r.r[0] = 3; /* set extent */
r.r[0] = OSArgs_SetEXT;
r.r[1] = (int)fh->destination_file_handle;
r.r[2] = 0; /* to 0 */
......@@ -1480,15 +1470,15 @@ dprintf( "T" );
/*
Write a block out
*/
gbpbplace.action = 1; /* write bytes at location */
gbpbplace.action = OSGBPB_WriteAtGiven;
gbpbplace.file_handle = fh->destination_file_handle;
gbpbplace.data_addr = buffer_base_address + buffer_offset + fh->start_of_buffer;
gbpbplace.number = amount_to_write;
gbpbplace.seq_point = fh->written_to;
#ifdef debugmem
dprintf( "w(%d,%d->%d)", (int)gbpbplace.data_addr, gbpbplace.number, gbpbplace.seq_point );
#endif
debugmem(( "int_write_a_block: buf %x + %d [%d-%d]\n", buffer_base_address, buffer_offset,
buffer_bottom, buffer_top ));
debugmem(( "int_write_a_block: w(%d,%u->%u)", (int)gbpbplace.data_addr, gbpbplace.number, gbpbplace.seq_point ));
t = clock();
......@@ -1511,9 +1501,7 @@ dprintf( "w(%d,%d->%d)", (int)gbpbplace.data_addr, gbpbplace.number, gbpbplace.s
{ /* if the transfer rate is suffering at this small blocksize,
* increase time_quanta to cause the blocksize to grow */
if (time_quanta < MaxTimeQuanta) time_quanta *= 2;
#ifdef debugmem
dprintf( "change time_quanta to %d\n", time_quanta );
#endif
debugmem(( "int_write_a_block: time_quanta to %d\n", time_quanta ));
}
if ( t < time_quanta - TimeQuantaHysteresis) dest_block_size = grow( dest_block_size );
if ( t > time_quanta + TimeQuantaHysteresis) dest_block_size = shrink( dest_block_size );
......@@ -1530,9 +1518,7 @@ dprintf( "change time_quanta to %d\n", time_quanta );
if ( !err && fh->write_state == write_closeit )
{
#ifdef debugmem
dprintf( "C" );
#endif
debugmem(( "C" ));
err = close_file( &fh->destination_file_handle );
/*
......@@ -1544,11 +1530,9 @@ dprintf( "C" );
if ( !err && fh->write_state == write_adjust_info )
{
#ifdef debugmem
dprintf( "I" );
#endif
debugmem(( "I" ));
/*
Always adjust the info as its almost always wrong
Always adjust the info as it's almost always wrong
*/
err = write_catalogue_information(
fh->destination_filename,
......@@ -1556,13 +1540,13 @@ dprintf( "I" );
fh->execute,
fh->attributes );
if ( err && fh->objecttype == ObjectType_Directory)
if ( err && fh->objecttype == object_directory)
{
/* Some FS's can't do this for a directory - back
off to just doing the access permission.
*/
err = NULL;
dont_set_dir_info = 1;
dont_set_dir_info = Yes;
fh->write_state = write_adjust_access;
}
else if ( !err )
......@@ -1571,9 +1555,7 @@ dprintf( "I" );
if ( !err && fh->write_state == write_adjust_access )
{
#ifdef debugmem
dprintf( "A" );
#endif
debugmem(( "A" ));
/*
Only adjust attributes if they're non-default ones
*/
......@@ -1588,20 +1570,40 @@ dprintf( "A" );
if ( !err && fh->write_state == write_all_done )
{
*that_finished_a_file = Yes;
#ifdef USE_PROGRESS_BAR
*progress = fh->write_progress;
#else
IGNORE(progress);
#endif
remove_file_from_chain();
#ifdef USE_PROGRESS_BAR
}
else
{
uint64_t p;
uint32_t b;
#ifdef debugmem
dprintf( "X\n" );
#endif
b = fh->written_to - start_written_to;
p = (fh->total_progress * (uint64_t)b) / fh->size;
fh->write_progress -= (uint32_t) p;
*progress = (uint32_t) p;
debugmem(( "partial write: %u bytes / %u = %08x progress\n", b, fh->size, *progress ));
#endif
}
debugmem(( "X\n" ));
return err;
}
os_error *write_a_block( int *i_am_empty, int *that_finished_a_file )
os_error *write_a_block( BOOL *i_am_empty, BOOL *that_finished_a_file, uint32_t *progress )
{
os_error *err = int_write_a_block( i_am_empty, that_finished_a_file );
os_error *err = int_write_a_block( i_am_empty, that_finished_a_file, progress );
if ( *i_am_empty )
{
......@@ -1650,9 +1652,7 @@ void restart_file_read( void )
{
files_header *fh = next_fh_to_read();
#ifdef debugmem
dprintf( "restart_file_read: fh=&08X\n", (int)fh );
#endif
debugmem(( "restart_file_read: fh=&08X\n", (int)fh ));
if ( fh != NULL )
{
......@@ -1669,9 +1669,7 @@ void restart_file_write( void )
{
files_header *fh = chain_link_Wrapper( files_chain.forwards );
#ifdef debugmem
dprintf( "restart_file_write: fh=&08X\n", (int)fh );
#endif
debugmem(( "restart_file_write: fh=&08X\n", (int)fh ));
if ( fh != NULL )
{
......@@ -1687,14 +1685,12 @@ dprintf( "restart_file_write: fh=&08X\n", (int)fh );
buffer_bottom -= fh->written_to;
fh->written_to = 0;
fh->write_state = write_not_started;
#ifdef debugmem
dprintf( "restarting write: start_of_buffer=%08X, buffer_bottom=%08X\n", fh->start_of_buffer, buffer_bottom );
#endif
debugmem(( "restart_file_write: start_of_buffer=%08X, buffer_bottom=%08X\n", fh->start_of_buffer, buffer_bottom ));
}
}
}
int bytes_left_to_read( void )
uint32_t bytes_left_to_read( void )
{
files_header *fh = next_fh_to_read();
......@@ -1708,7 +1704,7 @@ int bytes_left_to_read( void )
}
}
int bytes_left_to_write( void )
uint32_t bytes_left_to_write( void )
{
files_header *fh;
......@@ -1724,7 +1720,7 @@ int bytes_left_to_write( void )
}
}
void copy_go_faster( int do_it )
void copy_go_faster( BOOL do_it )
{
if ( do_it )
{
......
......@@ -15,11 +15,9 @@
/*
Header file for initialise.c
*/
#define wimp_MFilerSelectionDirectory 0x403
#define wimp_MFilerAddSelection 0x404
#define wimp_MFilerAction 0x405
#define wimp_MFilerControlAction 0x406
#define wimp_MSETSLOT 0x400c5
#define wimp_MFilerSelectionDirectory ((wimp_msgaction)0x403)
#define wimp_MFilerAddSelection ((wimp_msgaction)0x404)
#define wimp_MFilerAction ((wimp_msgaction)0x405)
#define wimp_MFilerControlAction ((wimp_msgaction)0x406)
os_error *initialise( action_environment *env, int argc, char *argv[] );
......@@ -19,18 +19,18 @@
#define OPTIONS_H
/* The faster button appears on the main window */
#define UseFasterButton
#define USE_FASTER_BUTTON
/* Are we using very long numbers in the boxes ? */
#define USE_LONG_LONG
/* (only if long numbers) use commas in the numbers */
/* Use commas in the numbers */
#define USE_COMMAS
/* Can we drag things to the window to perform more operations */
/* #define USE_LOAD_OPERATIONS */
/* Percent complete estimate shown */
#define USE_PROGRESS_BAR
/* Show completion in the title too */
#define USE_STATUS_IN_TITLE
/* Don't exempt some things - testing all */
/* #define CONFIRM_MEANS_CONFIRM_ALL */
/* Change dialogue box to red when fault occurs */
#undef USE_RED_ERROR
#endif
......@@ -88,21 +88,22 @@ typedef struct action_environment
/* wimplib handle onto the dialogue box */
dbox status_box;
/* wimp handle of the window */
int window_handle;
/* handle onto menu */
menu option_menu;
/* information regarding showing/hiding box in a delayed fashion */
int time_to_boxchange;
clock_t time_to_boxchange;
int boxchange_direction;
/* numeric quantities for progress lines */
#ifdef USE_LONG_LONG
uintmax_t top_progress;
uintmax_t bottom_progress;
#else
unsigned int top_progress;
unsigned int bottom_progress;
#endif
uint64_t top_progress;
uint64_t bottom_progress;
#ifdef USE_PROGRESS_BAR
uint32_t progress;
#endif
/* current overall operation (copying/counting/deleting etc) */
actions_possible operation;
......@@ -129,10 +130,10 @@ typedef struct action_environment
int source_directory_name_length;
/* Record of locked files not deleted */
int locked_not_deleted;
uint32_t locked_not_deleted;
/* Mask to use when setting access on directories for NetFS (KLUDGE) */
int directory_access_setting_mask;
uint32_t directory_access_setting_mask;
/* these indicate which switches apply */
int verbose:1;
......@@ -167,11 +168,13 @@ void switch_to_reading( action_environment * );
void switch_to_writing( action_environment * );
void show_faster_stuff( action_environment *env );
void toggle_faster( action_environment *env );
extern void set_top_info_field_with_current_info(action_environment *env, char *token1, char *token2);
extern char *last_top_info_field;
extern const char *last_top_info_field;
extern action_environment env;
extern int __root_stack_size;
/*
Delays for displaying verbose box and removing non-verbose box
in 1/100ths of a second
......@@ -183,7 +186,6 @@ extern int __root_stack_size;
/*
Dialogue box fields
*/
#define Top_Info_Field 1
#define Bottom_Info_Path 2
#define Top_Progress_Field 3
#define Bottom_Progress_Field 4
......@@ -195,11 +197,15 @@ extern int __root_stack_size;
#define Misc_Button 10
#define Skip_Button 11
#define Error_Field 12
#define Bottom_Info_Leaf 15
#define Progress_Bar 16
#define Progress_Bar_BBox 15
/* 1 less than the space allocated for the icon's indirected string */
#define Top_Info_Field_Length 79
/*
Window names
*/
#define Main_Window "FCount"
#define Info_Field_Length 64
#define MAIN_TEMPLATE_NAME "FCount"
#define QUERY_TEMPLATE_NAME "query"
......@@ -14,10 +14,4 @@
*/
/* Big numbers in dboxes */
#include "Options.h"
#ifdef USE_LONG_LONG
void dbox_setlongnumeric(dbox d, dbox_field f, uintmax_t n);
#else
#define dbox_setlongnumeric(x,y,z) dbox_setnumeric(x,y,z);
#endif
void dbox_setlongnumeric(dbox d, dbox_field f, uint64_t n);
......@@ -17,29 +17,30 @@
*/
#ifndef debug
#ifdef debugtube
#define debug
#else
#ifdef debugfile
#define debug
#endif
#endif
#ifdef debugtube
#define debug
#else
#ifdef debugfile
#define debug
#endif
#endif
#endif
#ifdef debug
#include "werr.h"
#define assert( e ) ((e) ? (void)0 : werr(1, "assert failed: '%s' in file %s at line %d", #e, __FILE__, __LINE__))
extern void dprintf( const char *str, ... );
#ifdef debugfile
extern FILE *debugf;
#endif
extern void dprintf( const char *str, ... );
#define IGNORE(x) (void)(x)
#define assert( e ) ((e) ? (void)0 : werr(1, "assert failed: '%s' in file %s at line %d", #e, __FILE__, __LINE__))
#else
#define IGNORE(x) (void)(x)
#define assert( ignore )
#endif