-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathiup.adb
231 lines (191 loc) · 8.18 KB
/
iup.adb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
-- The MIT License (MIT)
--
-- Copyright (c) 2014, Leonardo Cecchi
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
with Ada.Containers;
with Ada.Containers.Vectors;
with Interfaces.C;
with Interfaces.C.Strings;
package body Iup is
pragma Linker_Options("-liup");
package C renames Interfaces.C;
package CStrings renames Interfaces.C.Strings;
procedure Iup_Open(argc: System.Address; argv:System.Address);
pragma Import(C, Iup_Open, "IupOpen");
function Button(Title:String) return Handle is
function Iup_Button(title:C.char_array; Action:System.Address) return System.Address;
pragma Import(C, Iup_Button, "IupButton");
begin
return Handle(Iup_Button(C.To_C(Title), System.Null_Address));
end Button;
procedure Set_Attribute(Ih:Handle; name:String; value:String) is
procedure Iup_Store_Attribute(Id:Handle; name:C.char_array; value:C.char_array);
pragma Import(C, Iup_Store_Attribute, "IupStoreAttribute");
begin
Iup_Store_Attribute(Ih, C.To_C(name), C.To_C(Value));
end;
function Get_Attribute(Ih:Handle; name:String) return String is
use CStrings;
function Iup_Get_Attribute(Id:Handle; name:C.char_array) return chars_ptr;
pragma Import(C, Iup_Get_Attribute, "IupGetAttribute");
result: chars_ptr := Iup_Get_Attribute(Ih, C.To_C(name));
begin
if result = Null_Ptr then
return "";
else
return Cstrings.Value(result);
end if;
end;
function H_Box return Handle is
function Iup_Hbox(Nope:System.Address) return Handle;
pragma Import(C, Iup_Hbox, "IupHbox");
begin
return Iup_Hbox(System.Null_Address);
end;
function V_Box return Handle is
function Iup_Vbox(Nope:System.Address) return Handle;
pragma Import(C, Iup_Vbox, "IupVbox");
begin
return Iup_Vbox(System.Null_Address);
end;
function Z_Box return Handle is
function Iup_Zbox(Nope:System.Address) return Handle;
pragma Import(C, Iup_Zbox, "IupZbox");
begin
return Iup_Zbox(System.Null_Address);
end;
-- --------------------------------
-- Callback return value management
-- --------------------------------
function Callback_Result_To_Integer(Callback_Result: Callback_Result_Type) return Integer is
begin
case Callback_Result is
when Ignore => return -1;
when Default => return -2;
when Close => return -3;
when Continue => return -4;
when others => return -4;
end case;
end;
function Integer_To_Callback_Result(V: Integer) return Callback_Result_Type is
begin
if V=(-1) then
return Ignore;
elsif V=(-2) then
return Default;
elsif V=(-3) then
return Close;
elsif V=(-4) then
return Continue;
else
return Continue;
end if;
end;
function Loop_Step return Callback_Result_Type is
function Iup_Loop_Step return Integer;
pragma Import(C, Iup_Loop_Step, "IupLoopStep");
begin
return Integer_To_Callback_Result(Iup_Loop_Step);
end;
function Loop_Step_Wait return Callback_Result_Type is
function Iup_Loop_Step_Wait return Integer;
pragma Import(C, Iup_Loop_Step_Wait, "IupLoopStepWait");
begin
return Integer_To_Callback_Result(Iup_Loop_Step_Wait);
end;
-- ------------------------------------------
-- Callback management. Deep black magic here
-- ------------------------------------------
package Callback_Vector_Pkg is new Ada.Containers.Vectors(Positive, Callback_Type);
Ada_Callback_Prefix : constant String := "__ADA_CALLBACK_ID__";
Callback_Vector: Callback_Vector_Pkg.Vector;
subtype Callback_Id_Type is Ada.Containers.Count_Type;
function Internal_Callback(Ih:Handle) return Integer;
pragma Convention(C, Internal_Callback);
function Internal_Callback(Ih:Handle) return Integer is
use type CStrings.chars_ptr;
function Iup_Get_Action_Name return CStrings.chars_ptr;
pragma Import(C, Iup_Get_Action_Name, "IupGetActionName");
C_Callback_Name : CStrings.chars_ptr;
begin
C_Callback_Name := Iup_Get_Action_Name;
if C_Callback_Name = CStrings.Null_Ptr then
raise Program_Error with "IupAda callback invoked from a non Ada callback. Why?";
end if;
declare
Callback_Name : String := CStrings.Value(Iup_Get_Action_Name);
Callback_Id : Callback_Id_Type;
Callback_Result : Callback_Result_Type;
begin
if Callback_Name(Ada_Callback_Prefix'Range) /= Ada_Callback_Prefix then
raise Program_Error with "IupAda callback invoked with the wrong name " & Callback_Name & ". This sounds like an internal error";
end if;
Callback_Id := Callback_Id_Type'Value(Callback_Name(Ada_Callback_Prefix'Last+1..Callback_Name'Last));
Callback_Result := Callback_Vector_Pkg.Element(Callback_Vector, Positive(Callback_Id))(Ih);
return Callback_Result_To_Integer(Callback_Result);
exception
when Constraint_Error => raise Program_Error with "IupAda callback with the wrong id " & Callback_Name;
end;
end;
procedure Set_Callback(Ih:Handle; Name:String; Callback:Callback_Type) is
type Internal_Callback_Access is access function(Ih:Handle) return Integer;
pragma Convention(C, Internal_Callback_Access);
procedure Iup_Set_Callback(Ih:Handle; Name: C.char_array; Callback:Internal_Callback_Access);
pragma Import(C, Iup_Set_Callback, "IupSetCallback");
procedure Iup_Set_Function(Name: C.char_array; Callback:Internal_Callback_Access);
pragma Import(C, Iup_Set_Function, "IupSetFunction");
Callback_Id : Callback_Id_Type;
begin
Callback_Vector_Pkg.Append(Callback_Vector, Callback);
Callback_Id := Callback_Vector_Pkg.Length(Callback_Vector);
declare
Internal_Callback_Name : String := Ada_Callback_Prefix & Callback_Id_Type'Image(Callback_Id);
begin
Iup_Set_Function(C.To_C(Internal_Callback_Name), Internal_Callback'Access);
Set_Attribute(Ih, Name, Internal_Callback_Name);
end;
end;
procedure Append(Ih:Handle; Children: Handle_Array) is
begin
for i in Children'Range loop
Append(Ih, Children(i));
end loop;
end;
function Label(Title:String) return Handle is
function Iup_Label(Title:C.char_array) return Handle;
pragma Import(C, Iup_Label, "IupLabel");
begin
return Iup_Label(C.To_C(Title));
end;
function Grid_Box return Handle is
function Grid_Box(Nope: System.Address) return Handle;
pragma Import(C, Grid_Box, "IupGridBox");
begin
return Grid_Box(System.Null_Address);
end;
function Text return Handle is
function Iup_Text(Nope: System.Address) return Handle;
pragma Import(C, Iup_Text, "IupText");
begin
return Iup_Text(System.Null_Address);
end;
begin
Iup_Open(System.Null_Address, System.Null_Address);
end Iup;