{$M+} {$E+} PROGRAM Mock; {$I i:\opus.i} {$I i:\gctv.inc} {$I i:\auxsubs.def} {$I i:\gemsubs.def} PROCEDURE INT_TO_STRING ( a : INTEGER; VAR b : STR10 ); EXTERNAL; { VDI calls, n_ints = number of integers passed ** these mean to count ALL ** n_pts = number of point pairs passed } PROCEDURE VDI_Call ( cmd,sub_cmd : INTEGER; n_ints,n_pts : INTEGER; VAR control : Control_Parms; VAR int_in : Int_In_Parms; VAR int_out : Int_Out_Parms; VAR pts_in : Pts_In_Parms; VAR pts_out : Pts_Out_Parms; translate : BOOLEAN ); EXTERNAL; PROCEDURE Set_Char_Height ( height : INTEGER ); BEGIN pts_in[0] := 0; pts_in[1] := height; VDI_Call ( 12,0,0,1,control,int_in,int_out,pts_in,pts_out,FALSE ); END; { Set_Char_Height } PROCEDURE Text_Alignment ( horizontal : VDI_Just; vertical : INTEGER ); { affects the justification of text outputted with Draw_Just, and Draw_String for that matter } BEGIN int_in[0] := horizontal; int_in[1] := vertical; VDI_Call ( 39,0,2,0,control,int_in,int_out,pts_in,pts_out,FALSE ) END; PROCEDURE Draw_Just ( x, y : INTEGER; justification : VDI_Just; output_string : STR255 ); { VDI_Left - begins at x,y VDI_Center- begins so that center of string is at x,y VDI_Right - begins so that end of string is at x,y } BEGIN { bottom of character box; all Opus calls to this routine want this } Text_Alignment(justification,3); Draw_String(x,y,output_string) END; { DRAW_JUST } (* { this is the actual vst_justify call, which allows one to specify the length of the string and padding. However, this is quite useless as the "padding" doesn't erase the background! Moreover, calling with parameters of x,y,30,VDI_Right,'doug' results in 'doug' being placed at the far left instead of the far right! Really worthless... Use Draw_Just above if anything. } PROCEDURE Draw_Just ( x,y,text_length, justification : INTEGER; output_string : STR255 ); VAR i,n_ints : INTEGER; BEGIN Text_Alignment ( justification ); int_in[0] := 1; { space between words to achieve effect } int_in[1] := 0; { don't space between characters } FOR i := 1 TO LENGTH (output_string) DO int_in[i+1] := ORD(output_string[i]); n_ints := LENGTH(output_string)+2; pts_in[0] := x; pts_in[1] := y; pts_in[2] := text_length*8; VDI_Call ( 11,10,n_ints,2,control,int_in,int_out,pts_in,pts_out,FALSE ); END; *) (* PROCEDURE Rotate_Baseline ( angle : INTEGER ); { angle is a # between 0-3600, in 90 degree increments, i.e. 900=90 deg } BEGIN int_in[0] := angle; VDI_Call ( 13,0,1,0,control,int_in,int_out,pts_in,pts_out,FALSE ); END; *) PROCEDURE Create_User_Line_Type ( linetype : INTEGER ); BEGIN int_in[0] := linetype; VDI_Call ( 113,0,1,0,control,int_in,int_out,pts_in,pts_out,FALSE ); END; PROCEDURE User_Line_Style; BEGIN int_in[0] := 7; { user-defined line type } VDI_Call ( 15,0,1,0,control,int_in,int_out,pts_in,pts_out,FALSE ); END; (* PROCEDURE VQ_Mouse ( VAR x,y,button : INTEGER ); BEGIN VDI_Call ( 124,0,0,0,control,int_in,int_out,pts_in,pts_out,FALSE ); button := int_out[0]; x := pts_out[0]; y := pts_out[1] END; *) PROCEDURE Extended_Inquire ( info_flag : INTEGER ); BEGIN int_in[0] := info_flag; { 0=v_opnvwks; 1=extended parameters } VDI_Call ( 102,0,1,0,control,int_in,int_out,pts_in,pts_out,FALSE ) END; { Extended_Inquire } PROCEDURE Blit ( src,dst : Mfdb; from_x,from_y,to_x,to_y,width,height : INTEGER ); VAR temp : LONG_INTEGER; FUNCTION Addr ( VAR what : Mfdb ) : LONG_INTEGER; EXTERNAL; BEGIN { Blit } temp := Addr(src); control[7] := ShR(temp,16); { high } control[8] := temp & $0000FFFF; { low } temp := Addr(dst); control[9] := ShR(temp,16); control[10] := temp & $0000FFFF; int_in[0] := 3; { replace mode } pts_in[0] := from_x; pts_in[1] := from_y; pts_in[2] := from_x+width-1; pts_in[3] := from_y+height-1; pts_in[4] := to_x; pts_in[5] := to_y; pts_in[6] := to_x+width-1; pts_in[7] := to_y+height-1; VDI_Call ( 109,0,1,4,control,int_in,int_out,pts_in,pts_out,FALSE ); END; { Blit } (*****************************************************************************) { AES calls } PROCEDURE AES_Call ( op : INTEGER; VAR int_in : Int_In_Parms; VAR int_out : Int_Out_Parms; VAR addr_in:Addr_In_Parms; VAR addr_out:Addr_Out_Parms); EXTERNAL; FUNCTION PTR_TO_LONG ( addr : Generic_Ptr ) : LONG_INTEGER; { convert the address contained in the tree pointer into a long } VAR change : RECORD CASE byte OF 1 : ( original : Generic_Ptr ); 2 : ( final : LONG_INTEGER ); END; BEGIN change.original := addr; ptr_to_long := change.final END; { PTR_TO_LONG } PROCEDURE Write_Message ( ap_id,n_bytes : INTEGER; VAR msg_area : Message_Buffer ); FUNCTION Addr ( VAR what : Message_Buffer ) : LONG_INTEGER; EXTERNAL; BEGIN int_in[0] := ap_id; int_in[1] := n_bytes; addr_in[0] := Addr(msg_area); AES_Call ( 12,int_in,int_out,addr_in,addr_out ) END; { Write_Message } PROCEDURE Read_Message ( ap_id,n_bytes : INTEGER; VAR msg_area : Message_Buffer ); FUNCTION Addr ( VAR what : Message_Buffer ) : LONG_INTEGER; EXTERNAL; BEGIN int_in[0] := ap_id; int_in[1] := n_bytes; addr_in[0] := Addr(msg_area); AES_Call ( 11,int_in,int_out,addr_in,addr_out ); END; { Read_Message } PROCEDURE Get_Text ( tree : Generic_Ptr; index : Tree_Index; VAR p_s : P_EdText ); { complementary to Set_Text below } CONST obj_len = 24; TYPE C_EdTextPtr = ^C_EdText; VAR i : INTEGER; ob_spec_addr,ted_info_addr,text_addr : LONG_INTEGER; c_s : C_EdTextPtr; FUNCTION Ptr ( where : LONG_INTEGER ) : C_EdTextPtr; EXTERNAL; BEGIN ob_spec_addr := ptr_to_long(tree)+index*obj_len+12; ted_info_addr := Lpeek(ob_spec_addr); text_addr := Lpeek (ted_info_addr); { first thing in tedinfo } c_s := Ptr(text_addr); { get a pointer to the tedinfo string } p_s := ''; { and convert c-string to Pascal string } i := 1; WHILE c_s^[i] <> CHR(0) DO BEGIN p_s := CONCAT(p_s,c_s^[i]); i := i+1 END END; { Get_Text } PROCEDURE Set_Text ( tree : Generic_Ptr; { dialog ptr } index : INTEGER; { which item } p_str : STR255; { a pascal string to show } VAR c_str : C_EdText; { C string ptr } text_len : INTEGER ); { max length of the text } { Procedure to replace both Set_DText & Set_DEdit. Must pass a pascal string, even a null, and a C string of type C_EdText. Set_Text allows you to use an RCS and leave the text fields unoccupied, save for template and validation if FTEXT, and then in Pascal, avoid the use of SetDEdit which REQUIRES you to enter the temp, val, and initial string fields as its parameters, wasting lots of memory ( and a pain ). And you can read the text fields with Get_DEdit, which still works fine, or use Get_Text above to avoid Get_DEdit's requirement of a STR255 } CONST obj_len = 24; VAR i : INTEGER; ob_spec_addr,ted_info_addr,text_addr : LONG_INTEGER; FUNCTION Addr ( VAR a : C_EdText ) : LONG_INTEGER; EXTERNAL; BEGIN { Set_Text } { convert pascal string to a C string, terminated with a zero-byte } FOR i := 1 TO LENGTH(p_str) DO c_str[i] := p_str[i]; c_str[LENGTH(p_str)+1] := CHR(0); { address of string = area the form manager writes in when user modifies editable text fields } text_addr := Addr(c_str); { now calculate the address within this item's object tree of this item's object spec, which equals: address of the tree ( Dialog_Ptr ) PLUS item index*obj_len; obj_len = 24, since each item in a tree has a 24 byte entry defining it, and these block begin at the tree address. The root has index 0, and the rest are numbered 1,2,3...n PLUS 12, the offset within an item's block for the object spec, which in the case of any TEXT type object, contains a pointer to a TEDINFO data structure } ob_spec_addr := ptr_to_long(tree)+index*obj_len+12; ted_info_addr := Lpeek(ob_spec_addr); { peek into this address } { poke address of the string to be outputted,and if FTEXT mixed with the template, into the first field of tedinfo } Lpoke(ted_info_addr,text_addr); { and finally poke the maximum length of the string into tedinfo. NOTE the max length includes the zero-byte terminator! } Wpoke(ted_info_addr+24,text_len+1); END; { Set_Text } FUNCTION Map_Tree ( tree : Generic_Ptr; start_index,end_index : Tree_Index; action : MapAction ) : Tree_Index; { func to traverse an entire form tree, visiting every node and depending on the value of 'action', deselecting all the selectable objects or returning the value of the selected one. If the whole tree is to be traversed, start_index should = 'Root' and end_index should equal 'Null_Index', i.e. 0 and -1. This is the case to deselect every object with action = 'clear_Selected'. To determine which object is selected, a range should be passed, i.e. the first radio button to the last in a set of radio buttons, and action should = 'return_Selected'. It returns the index of the LAST selected item it found within the range. If none were found, or action = clear_Selected, Null_Index is returned. This is taken from Tim Oren's Pro Gem column 5. Be warned- no error checking is done! } CONST next = 0; head = 2; tail = 4; obj_len = 24; VAR tree_addr : LONG_INTEGER; temp,cur_index : Tree_Index; { these function return the contents of the Ob_next, Ob_head, and Ob_tail fields of the object specified by index 'temp' } FUNCTION Obj_Next ( temp : Tree_Index ) : INTEGER; BEGIN Obj_Next := Wpeek(tree_addr+temp*obj_len+next) END; FUNCTION Obj_Head ( temp : Tree_Index ) : INTEGER; BEGIN Obj_Head := Wpeek(tree_addr+temp*obj_len+head) END; FUNCTION Obj_Tail ( temp : Tree_Index ) : INTEGER; BEGIN Obj_Tail := Wpeek(tree_addr+temp*obj_len+tail) END; BEGIN Map_Tree := Null_Index; tree_addr := ptr_to_long(tree); cur_index := start_index; temp := start_index; { note Tim Oren had specified current_index instead of temp in the first comparison in the WHILE. This would cause you NOT to check the last item! temp is the correct variable. } WHILE (temp <> end_index) AND (cur_index <> Null_Index) DO IF Obj_Tail(cur_index) <> temp THEN BEGIN { through with node? } temp := cur_index; { no, save it's index for comparison later } IF action = ClearSelected THEN IF (Obj_Flags(tree,temp) & 1) <> 0 THEN { Selectable? } Obj_SetState (tree,temp,Normal,FALSE) { yes, make it nl } ELSE ELSE { see if selected - note it assumes proper range was sent. otherwise it returns the value of the last selected object it encountered; if none were found, Null_Index is returned } IF (Obj_State(tree,temp) & Selected) <> 0 THEN Map_Tree := temp; cur_index := Obj_Head(temp); { child? if so advance to it } IF cur_index = Null_Index THEN { no kids, so get next object } cur_index := Obj_Next(temp) END ELSE BEGIN { obj_tail = current index, so we've done this node and any children it had. Go to next node. } temp := cur_index; cur_index := Obj_Next(temp) END END; { Map_Tree } PROCEDURE Form_Center ( box : Dialog_Ptr; VAR fo_x,fo_y,fo_w,fo_h : INTEGER ); BEGIN addr_in[0] := ptr_to_long(box); AES_Call ( 54,int_in,int_out,addr_in,addr_out ); fo_x := int_out[1]; fo_y := int_out[2]; fo_w := int_out[3]; fo_h := int_out[4]; END; { Form_Center } PROCEDURE Form_Anywhere ( box : Dialog_Ptr; x,y : INTEGER; VAR w,h : INTEGER ); VAR addr : LONG_INTEGER; BEGIN addr := ptr_to_long(box); WPoke(addr+16,x); WPoke(addr+18,y); w := WPeek(addr+20); h := WPeek(addr+22) END; { Form_Anywhere } PROCEDURE Form_Dial ( fn,little_x,little_y,little_w,little_h, big_x,big_y,big_w,big_h : INTEGER ); BEGIN int_in[0] := fn; int_in[1] := little_x; int_in[2] := little_y; int_in[3] := little_w; int_in[4] := little_h; int_in[5] := big_x; int_in[6] := big_y; int_in[7] := big_w; int_in[8] := big_h; AES_Call ( 51,int_in,int_out,addr_in,addr_out ); END; { Form_Dial } FUNCTION Form_Do ( box : Dialog_Ptr; index : Tree_Index ) : Tree_Index; BEGIN int_in[0] := index; addr_in[0] := ptr_to_long(box); AES_Call(50,int_in,int_out,addr_in,addr_out); form_do := int_out[0] & $7FFF { if double click on EXIT item, then } END; { Form_Do } { high bit will be set. To suppress. } PROCEDURE Rubber_Box ( x,y,sm_w,sm_h : INTEGER; VAR last_width,last_height : INTEGER ); BEGIN int_in[0] := x; int_in[1] := y; int_in[2] := sm_w; int_in[3] := sm_h; AES_Call ( 70,int_in,int_out,addr_in,addr_out ); last_width := int_out[1]; { return values to caller } last_height := int_out[2]; END; { Rubber_Box } PROCEDURE Drag_Box ( inner_x,inner_y, inner_w,inner_h, outer_x,outer_y, outer_w,outer_h : INTEGER; VAR n_inner_x,n_inner_y : INTEGER ); BEGIN int_in[0] := inner_w; int_in[1] := inner_h; int_in[2] := inner_x; int_in[3] := inner_y; int_in[4] := outer_x; int_in[5] := outer_y; int_in[6] := outer_w; int_in[7] := outer_h; AES_Call ( 71,int_in,int_out,addr_in,addr_out ); n_inner_x := int_out[1]; n_inner_y := int_out[2]; END; PROCEDURE Form_Error ( tos_error_num : INTEGER ); VAR temp,temp1 : STR255; BEGIN Set_Mouse(M_Arrow); IF tos_error_num >= -17 THEN BEGIN int_to_string(ABS(tos_error_num),temp1); temp1 := CONCAT('[1][BIOS error # -',temp1); CASE tos_error_num OF -1,-12 : temp := 'General error'; -2 : temp := 'Drive was not ready'; -3 : temp := 'Unknown command'; -4 : temp := 'CRC error'; -5 : temp := 'Bad request'; -6 : temp := 'Seek error'; -7 : temp := 'Unknown media'; -8 : temp := 'Sector not found'; -9 : temp := 'No paper'; -10 : temp := 'Write error'; -11 : temp := 'Read error'; -13 : temp := 'Disk is write-protected'; -14 : temp := 'Media was changed'; -15 : temp := 'Unknown device'; -16 : temp := 'Bad sector'; -17 : temp := 'Insert disk' END; temp := CONCAT(temp1,'| | ',temp,'.][ Cancel ]'); alert := Do_Alert(temp,1) END ELSE BEGIN IF ((tos_error_num <= -33) AND (tos_error_num >= -36)) OR (tos_error_num = -39) OR (tos_error_num = -46) OR (tos_error_num = -49) THEN int_in[0] := -(tos_error_num+31) ELSE int_in[0] := tos_error_num; AES_Call(53,int_in,int_out,addr_in,addr_out) END END; (* Form_Error *) FUNCTION Obj_Find ( tree : Dialog_Ptr; firstob,depth : Tree_Index; x,y : INTEGER; VAR result : Tree_Index ) : BOOLEAN; BEGIN int_in[0] := firstob; int_in[1] := depth; int_in[2] := x; int_in[3] := y; addr_in[0] := ptr_to_long(tree); AES_Call(43,int_in,int_out,addr_in,addr_out); result := int_out[0]; IF result < 0 THEN Obj_Find := FALSE ELSE Obj_Find := TRUE END; { Obj_Find } FUNCTION Wind_Find ( x,y : INTEGER ) : INTEGER; BEGIN int_in[0] := x; int_in[1] := y; AES_Call(106,int_in,int_out,addr_in,addr_out); Wind_Find := int_out[0] END; { Wind_Find } PROCEDURE Graf_MKState ( VAR x,y,btn_state,key_state : INTEGER ); BEGIN AES_Call(79,int_in,int_out,addr_in,addr_out); x := int_out[1]; y := int_out[2]; btn_state := int_out[3]; key_state := int_out[4] END; { Graf_MKState } { PROCEDURE Grow_Shrink( cmd, small_x, small_y, small_w, small_h, big_x, big_y, big_w, big_h : INTEGER ); BEGIN int_in[0] := small_x; int_in[1] := small_y; int_in[2] := small_w; int_in[3] := small_h; int_in[4] := big_x; int_in[5] := big_y; int_in[6] := big_w; int_in[7] := big_h; AES_Call( cmd, int_in, int_out, addr_in, addr_out ); END; PROCEDURE Grow_Box ( small_x, small_y, small_w, small_h, big_x, big_y, big_w, big_h : INTEGER ); BEGIN Grow_Shrink ( 73, small_x, small_y, small_w, small_h, big_x, big_y, big_w, big_h ); END; PROCEDURE Shrink_Box ( big_x, big_y, big_w, big_h, small_x, small_y, small_w, small_h : INTEGER ); BEGIN Grow_Shrink ( 74, small_x, small_y, small_w, small_h, big_x, big_y, big_w, big_h ); END; PROCEDURE Set_Resource_Address ( res_type,res_index : INTEGER; VAR res_addr : Generic_Ptr ); BEGIN int_in[0] := res_type; int_in[1] := res_index; addr_in[0] := res_addr; AES_Call ( 113,int_in,int_out,addr_in,addr_out ); END; PROCEDURE Obj_Edit ( index,character,next_pos,edit_fn : INTEGER; res_addr : Generic_Ptr ); BEGIN int_in[0] := index; int_in[1] := character; int_in[2] := next_pos; int_in[3] := edit_fn; addr_in[0] := res_addr; AES_Call ( 46,int_in,int_out,addr_in,addr_out ); END; FUNCTION Menu_Register ( ap_id : INTEGER; VAR acc_name : STR255 ) : INTEGER; EXTERNAL; PROCEDURE Graf_MKState ( VAR x,y,buttons,keys : INTEGER ); BEGIN AES_Call ( 79,int_in,int_out,addr_in,addr_out ); x := int_out[1]; y := int_out[2]; buttons := int_out[3]; keys := int_out[4]; END; PROCEDURE Move_Box ( o_x,o_y,w,h,n_x,n_y : INTEGER ); BEGIN int_in[1] := w; int_in[2] := h; int_in[3] := o_x; int_in[4] := o_y; int_in[5] := n_x; int_in[6] := n_y; AES_Call ( 72,int_in,int_out,addr_in,addr_out ); END; } BEGIN END.