   10REM > !RunImage
   20REM Authors : Neil Gardner, Updates by James Bye
   30version$="1.02 (31-Oct-90)"
   40PROCinitialise
   50ON ERROR PROCerror
   60REPEAT
   70SYS"Wimp_Poll",0,q1% TO r%
   80CASE r% OF
   90WHEN 0    : IF stage%=3 PROCcopy_files
  100WHEN 2    : SYS"Wimp_OpenWindow",,q1%
  110WHEN 3    : SYS"Wimp_CloseWindow",,q1%
  120IF!q1%=SysUpdate% PROCshutdown:END
  130WHEN 6    : PROCmouseclick
  140WHEN 7    : PROCdecodedrag
  150WHEN 9    : PROCmenuselect
  160WHEN 17,18: PROCreceive(r%)
  170ENDCASE
  180UNTIL FALSE
  190END
  200:
  210DEF PROCinitialise
  220error_flag%=3
  230DIM ws% 2048:wsend%=ws%+2048
  240DIM menufree% 256:menuend%=menufree%+256
  250DIM q1% 256, q2% 512
  260SYS"Wimp_Initialise",200,&4B534154,"SysMerge"
  270SYS"Wimp_OpenTemplate",,"<SysUpdate$Dir>.Templates"
  280SYS"Wimp_LoadTemplate",,q2%,ws%,wsend%,-1,"info",0 TO ,,ws%
  290$(q2%!(88+96+20))=version$
  300SYS"Wimp_CreateWindow",,q2% TO info%
  310SYS"Wimp_LoadTemplate",,q2%,ws%,wsend%,-1,"system",0 TO ,,ws%,,,,r6%
  320file1%=q2%!(88+64+20)
  330file2%=q2%!(88+96+20)
  340prompt%=q2%!(88+128+20)
  350SYS"Wimp_CreateWindow",,q2% TO SysUpdate%
  360SYS"Wimp_CloseTemplate"
  370mainmenu%=FNcrmenu
  380DATA"#SysMerge,Info>info%,Quit"
  390PROCinit_sys_window
  400saveref%=0
  410error_flag%=3
  420PROCgetmodeinfo
  430!q1%=SysUpdate%:SYS"Wimp_GetWindowState",,q1%:SYS"Wimp_OpenWindow",,q1%
  440ENDPROC
  450:
  460DEF PROCinit_sys_window
  470$file1%=""
  480$file2%=""
  490$prompt%="Drag the original !System into this window."
  500stage%=1
  510PROCrefresh_sys_window
  520ENDPROC
  530:
  540DEF PROCgetmodeinfo
  550q1%!0 = 4
  560q1%!4 = 5
  570q1%!8 = 11
  580q1%!12= 12
  590q1%!16= -1
  600SYS"OS_ReadVduVariables",q1%,q1%+20
  610dx%=1<<(q1%!20)
  620dy%=1<<(q1%!24)
  630scrx1%=(q1%!28+1)*dx%
  640scry1%=(q1%!32+1)*dy%
  650ENDPROC
  660:
  670DEF PROCmouseclick
  680LOCAL p%
  690CASE q1%!8 OF
  700WHEN 2:   IF q1%!12=SysUpdate% PROCdomenu(mainmenu%,!q1%-64,q1%!4)
  710ENDCASE
  720ENDPROC
  730:
  740DEF PROCdecodedrag
  750LOCAL f1%,f2%,h%,i%,mx%,my%,ext%
  760f1%=OPENIN("<SysUpdate$Dir>.Output"):ext%=EXT#f1%:CLOSE#f1%
  770f1%=filename%
  780REPEAT
  790f2%=f1%
  800f1%+=INSTR($f1%,".")
  810UNTIL f1%=f2%
  820SYS"Wimp_GetPointerInfo",,q1%
  830mx%=!q1%
  840my%=q1%!4
  850h%=q1%!12
  860i%=q1%!16
  870!q1%=(48+LEN$f1%)AND NOT 3
  880q1%!12=0
  890q1%!16=1
  900q1%!20=h%
  910q1%!24=i%
  920q1%!28=mx%
  930q1%!32=my%
  940q1%!36=ext%
  950q1%!40=&FFF
  960$(q1%+44)=$f1%
  970?(q1%+44+LEN$(q1%+44))=0
  980SYS"Wimp_SendMessage",17,q1%,h%,i%
  990saveref%=q1%!8
 1000ENDPROC
 1010:
 1020DEF PROCdomenu(h%,x%,y%)
 1030menudata%=h%:menux%=x%:menuy%=y%
 1040SYS"Wimp_CreateMenu",,h%,x%,y%
 1050ENDPROC
 1060:
 1070DEF PROCmenuselect
 1080LOCAL a$,i%
 1090SYS"Wimp_DecodeMenu",,menudata%,q1%,STRING$( 200," ") TO ,,,a$
 1100IF a$="" ENDPROC
 1110IF a$="Quit" PROCshutdown:END
 1120ENDPROC
 1130:
 1140DEF FNrtoz(p%)
 1150LOCAL q$
 1160WHILE ?p%<>0 q$+=CHR$?p%:p%+=1:ENDWHILE
 1170=q$
 1180:
 1190DEF PROCreceive(r%)
 1200LOCAL name$,i%,x%
 1210CASE q1%!16 OF
 1220WHEN 0: PROCshutdown:END
 1230WHEN 1: REM file dropped from application - return filename
 1240PROCok("Application data cannot be merged")
 1250ENDPROC
 1260WHEN 3: REM file dropped from Filer - identify object
 1270CASE stage% OF
 1280WHEN 1: PROCcheck_type
 1290$file1%=FNrtoz(q1%+44)
 1300$prompt%="Drag the new !System into this window"
 1310PROCrefresh_sys_window
 1320stage%=2
 1330WHEN 2: PROCcheck_type
 1340$file2%=FNrtoz(q1%+44)
 1350IF$file1%=$file2% THEN
 1360PROCinit_sys_window
 1370PROCok("The files are identical")
 1380ENDIF
 1390$prompt%="Please wait ... processing files"
 1400PROCrefresh_sys_window
 1410stage%=3
 1420ENDCASE
 1430WHEN&502: PROCinteractive_help
 1440WHEN&400C1: PROCgetmodeinfo
 1450ENDCASE
 1460ENDPROC
 1470:
 1480DEF PROCinteractive_help
 1490LOCAL t$
 1500CASE q1%!32 OF
 1510WHEN SysUpdate%: t$="This is the SysMerge window.|M"
 1520CASE stage% OF
 1530WHEN 1: t$+="Drop the original !System on it."
 1540WHEN 2: t$+="Drop the new !System on it."
 1550WHEN 4: t$+="!System update was successful.|MClick SELECT on close icon to quit."
 1560ENDCASE
 1570ENDCASE
 1580IF t$<>"" THEN
 1590q1%!12=q1%!8
 1600q1%!16=&503
 1610$(q1%+20)=t$+CHR$ 0
 1620!q1%=(25+LEN t$)AND NOT 3
 1630SYS"Wimp_SendMessage",17,q1%,q1%!4
 1640ENDIF
 1650ENDPROC
 1660:
 1670DEF PROCcheck_type
 1680IF q1%!40<>&2000 OR RIGHT$(FNupper(FNrtoz(q1%+44)),8)<>".!SYSTEM" THEN PROCok("This is not a system resource directory")
 1690ENDPROC
 1700:
 1710DEF PROCrefresh_sys_window
 1720!q2%=SysUpdate%:q2%!4=2:q2%!8=0:q2%!12=0:SYS"Wimp_SetIconState",,q2%
 1730!q2%=SysUpdate%:q2%!4=3:q2%!8=0:q2%!12=0:SYS"Wimp_SetIconState",,q2%
 1740!q2%=SysUpdate%:q2%!4=4:q2%!8=0:q2%!12=0:SYS"Wimp_SetIconState",,q2%
 1750ENDPROC
 1760:
 1770DEF PROCshutdown
 1780SYS"Wimp_CloseDown"
 1790ENDPROC
 1800:
 1810DEF PROCerror
 1820IF error_flag%=3 THEN
 1830PROCerrorbox("Unexpected error :- "+REPORT$+" ("+STR$(ERL)+")")
 1840ELSE
 1850PROCerrorbox(REPORT$)
 1860ENDIF
 1870error_flag%=3
 1880ENDPROC
 1890:
 1900DEF PROCok(e$)
 1910error_flag%=1
 1920ERROR 1,e$
 1930ENDPROC
 1940:
 1950DEF PROCfatal(e$)
 1960error_flag%=2
 1970ERROR 1,e$
 1980ENDPROC
 1990:
 2000DEF PROCerrorbox(r$)
 2010LOCAL r%
 2020!q1%=ERR:$(q1%+4)=r$+CHR$ 0
 2030SYS"Wimp_ReportError",q1%,error_flag%,"SysMerge utility" TO ,r%
 2040IF r%=2 SYS"Wimp_CloseDown":END
 2050ENDPROC
 2060:
 2070DEF FNcrmenu
 2080LOCAL m%,menu$,m$
 2090IF (menufree%+28>menuend%) PROCfatal("Menu area full")
 2100READ menu$
 2110WHILE RIGHT$( menu$,2)="++"
 2120READ m$
 2130menu$=LEFT$( menu$,LEN menu$-2)+m$
 2140ENDWHILE
 2150menuptr%=menufree%
 2160i%=0
 2170IF LEFT$( menu$,1)="#" i%=1:menutitle$=FNpar(",") ELSE menutitle$=""
 2180$menuptr%=menutitle$
 2190menuptr%?12=7
 2200menuptr%?13=2
 2210menuptr%?14=7
 2220menuptr%?15=1
 2230menuptr%!16=196
 2240menuptr%!20=44
 2250menuptr%!24=0
 2260menuptr%+=28
 2270maxx%=LEN menutitle$-3
 2280REPEAT
 2290item$=FNpar(",")
 2300PROCmenuitem(item$)
 2310UNTIL item$=""
 2320m%=menufree%
 2330m%!16=(maxx%*8+6)*2
 2340menufree%=menuptr%
 2350=m%
 2360:
 2370DEF PROCmenuitem(text$)
 2380LOCAL i%,flg%,subptr%,L%
 2390IF text$="" menuptr%!-24=(menuptr%!-24)OR&80:ENDPROC
 2400IF (menuptr%+24>menuend%) PROCfatal("Menu area full")
 2410flg%=&00
 2420i%=INSTR( text$,">")
 2430IF i%>0 THEN
 2440subptr%=EVAL MID$( text$,i%+1)
 2450text$=LEFT$( text$,i%-1)
 2460ELSE
 2470subptr%=-1
 2480ENDIF
 2490IF RIGHT$( text$,1)="#" text$=LEFT$( text$,LEN text$-1):flg%+=&02
 2500menuptr%!0=flg%
 2510menuptr%!4=subptr%
 2520menuptr%!8=&07000021
 2530IF LEFT$( text$,1)="$" THEN
 2540!menuptr%+=&04
 2550menuptr%!8+=&100
 2560i%=INSTR( text$,"(")
 2570IF i%>0 THEN
 2580L%=VAL MID$( text$,i%+1)
 2590text$=LEFT$( text$,i%-1)
 2600ELSE
 2610L%=12
 2620ENDIF
 2630menuptr%!12=EVAL MID$( text$,2)
 2640menuptr%!16=-1
 2650menuptr%!20=L%
 2660IF L%>16 L%=16
 2670text$=STRING$( L%," ")
 2680ELSE
 2690IF LEN text$<=12 THEN
 2700$(menuptr%+12)=text$
 2710ELSE
 2720I%=FNworkspace(LEN text$+1):$I%=text$
 2730menuptr%!12=I%:menuptr%!16=-1:menuptr%!20=LEN text$+1
 2740menuptr%!8=menuptr%!8 OR &100
 2750ENDIF
 2760ENDIF
 2770IF LEN text$>maxx% maxx%=LEN text$
 2780menuptr%+=24
 2790ENDPROC
 2800:
 2810DEF FNpar(sep$)
 2820LOCAL i1%
 2830i1%=i%+1
 2840i%=INSTR( menu$+sep$,sep$,i1%)
 2850=MID$( menu$,i1%,i%-i1%)
 2860:
 2870DEF PROCshade(menuhandle%,item%)
 2880menuhandle%!(28+8+24*item%)=menuhandle%!(28+8+24*item%)EOR&400000
 2890ENDPROC
 2900:
 2910DEF FNshade_status(menuhandle%,item%)
 2920= -((menuhandle%!(28+8+24*item%) AND &400000)=&400000)
 2930:
 2940DEF PROCset_shade(menuhandle%,item%,value%)
 2950IF FNshade_status(menuhandle%,item%)<>value% PROCshade(menuhandle%,item%)
 2960ENDPROC
 2970:
 2980DEF PROCtick(menuhandle%,item%)
 2990menuhandle%!(28+24*item%)=menuhandle%!(28+24*item%)EOR 1
 3000ENDPROC
 3010:
 3020DEF FNtick_status(menuhandle%,item%)
 3030= menuhandle%!(28+24*item%)AND 1
 3040:
 3050DEF PROCset_tick(menuhandle%,item%,value%)
 3060IF FNtick_status(menuhandle%,item%)<>value% PROCtick(menuhandle%,item%)
 3070ENDPROC
 3080:
 3090DEF FNworkspace(L%)
 3100IF curws%+L%>ws%+maxws% THEN PROCfatal("No more workspace")
 3110curws%+=L%
 3120=curws%-L%
 3130:
 3140DEF PROCcopy_files
 3150SYS"Hourglass_On"
 3160SYS"XOS_FSControl",26,$file2%,$file1%,%101001000000011 TO r0%;reg%
 3170IF (reg%AND 1)=1 THEN
 3180error_flag%=1:PROCerrorbox(FNrtoz(r0%+4)):error_flag%=3
 3190$file1%=""
 3200$file2%=""
 3210$prompt%="!System Update failed.  Correct the problem then drag the original !System into this window."
 3220stage%=1
 3230PROCrefresh_sys_window
 3240ENDPROC
 3250ENDIF
 3260REM OSCLI"copy "+$file2%+" "+$file1%+" rnf~c~va~dl~p~q~s~t"1
 3270stage%=4
 3280$prompt%="!System updated."
 3290PROCrefresh_sys_window
 3300SYS"Hourglass_Off"
 3310ENDPROC
 3320:
 3330DEF FNupper(str$)
 3340LOCAL rtn$, l%, c$
 3350rtn$=""
 3360FOR l%=1 TO LEN str$
 3370c$=MID$( str$,l%,1)
 3380IF c$>="a" AND c$<="z" THEN
 3390rtn$+=CHR$(ASC c$EOR&20)
 3400ELSE
 3410rtn$+=c$
 3420ENDIF
 3430NEXT
 3440=rtn$
