~ubuntu-branches/ubuntu/jaunty/vala/jaunty

« back to all changes in this revision

Viewing changes to gobject/valadbusclientmodule.vala

  • Committer: Bazaar Package Importer
  • Author(s): Marc-Andre Lureau
  • Date: 2009-02-20 23:46:29 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20090220234629-erhhgnj4zdpech68
Tags: 0.5.7-1
New upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
/**
29
29
 * The link between a dynamic method and generated code.
30
30
 */
31
 
public class Vala.DBusClientModule : DBusModule {
 
31
internal class Vala.DBusClientModule : DBusModule {
32
32
        int dynamic_property_id;
33
33
 
34
34
        public DBusClientModule (CCodeGenerator codegen, CCodeModule? next) {
48
48
        public override void generate_dynamic_method_wrapper (DynamicMethod method) {
49
49
                var dynamic_method = (DynamicMethod) method;
50
50
 
51
 
                var func = new CCodeFunction (method.get_cname (), method.return_type.get_cname ());
 
51
                var func = new CCodeFunction (method.get_cname ());
52
52
 
53
53
                var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
54
54
 
55
 
                generate_cparameters (method, method.return_type, false, cparam_map, func);
 
55
                generate_cparameters (method, cparam_map, func);
56
56
 
57
57
                var block = new CCodeBlock ();
58
58
                if (dynamic_method.dynamic_type.data_type == dbus_object_type) {
184
184
                        ccall.add_argument (new CCodeIdentifier (cb_fun.name));
185
185
                        ccall.add_argument (new CCodeConstant ("param%d_target".printf (callback_index)));
186
186
                        ccall.add_argument (new CCodeConstant ("NULL"));
187
 
                } else if (found_out || !(method.return_type is VoidType)) {
 
187
                } else { 
188
188
                        ccall.call = new CCodeIdentifier ("dbus_g_proxy_call");
189
189
 
190
190
                        ccall.add_argument (new CCodeIdentifier ("error"));
191
 
                } else {
192
 
                        ccall.call = new CCodeIdentifier ("dbus_g_proxy_call_no_reply");
193
191
                }
194
192
 
195
193
                foreach (FormalParameter param in method.get_parameters ()) {
433
431
                                block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
434
432
                        }
435
433
                } else {
436
 
                        if (found_out) {
437
 
                                ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
438
 
                        }
 
434
                        ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
439
435
 
440
436
                        block.add_statement (new CCodeExpressionStatement (ccall));
441
437
 
875
871
 
876
872
                source_type_member_definition.append (new CCodeExpressionStatement (define_type));
877
873
 
 
874
                // generate proxy_new function
878
875
                var proxy_new = new CCodeFunction (lower_cname + "_new", iface.get_cname () + "*");
879
876
                proxy_new.add_parameter (new CCodeFormalParameter ("connection", "DBusGConnection*"));
880
877
                proxy_new.add_parameter (new CCodeFormalParameter ("name", "const char*"));
882
879
 
883
880
                var new_block = new CCodeBlock ();
884
881
 
 
882
                // create proxy object
885
883
                var new_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_new"));
886
884
                new_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier (lower_cname + "_get_type")));
887
885
                new_call.add_argument (new CCodeConstant ("\"connection\""));
894
892
                new_call.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name)));
895
893
                new_call.add_argument (new CCodeConstant ("NULL"));
896
894
 
897
 
                new_block.add_statement (new CCodeReturnStatement (new_call));
 
895
                var cdecl = new CCodeDeclaration (iface.get_cname () + "*");
 
896
                cdecl.add_declarator (new CCodeVariableDeclarator ("self", new_call));
 
897
                new_block.add_statement (cdecl);
 
898
 
 
899
                var raw_connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection"));
 
900
                raw_connection.add_argument (new CCodeIdentifier ("connection"));
 
901
 
 
902
                // add filter to handle signals from the remote object
 
903
                var filter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_add_filter"));
 
904
                filter_call.add_argument (raw_connection);
 
905
                filter_call.add_argument (new CCodeIdentifier (lower_cname + "_filter"));
 
906
                filter_call.add_argument (new CCodeIdentifier ("self"));
 
907
                filter_call.add_argument (new CCodeConstant ("NULL"));
 
908
                new_block.add_statement (new CCodeExpressionStatement (filter_call));
 
909
 
 
910
                var filter_printf = new CCodeFunctionCall (new CCodeIdentifier ("g_strdup_printf"));
 
911
                filter_printf.add_argument (new CCodeConstant ("\"type='signal',path='%s'\""));
 
912
                filter_printf.add_argument (new CCodeIdentifier ("path"));
 
913
 
 
914
                cdecl = new CCodeDeclaration ("char*");
 
915
                cdecl.add_declarator (new CCodeVariableDeclarator ("filter", filter_printf));
 
916
                new_block.add_statement (cdecl);
 
917
 
 
918
                // ensure we receive signals from the remote object
 
919
                var match_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_bus_add_match"));
 
920
                match_call.add_argument (raw_connection);
 
921
                match_call.add_argument (new CCodeIdentifier ("filter"));
 
922
                match_call.add_argument (new CCodeConstant ("NULL"));
 
923
                new_block.add_statement (new CCodeExpressionStatement (match_call));
 
924
 
 
925
                var filter_free = new CCodeFunctionCall (new CCodeIdentifier ("g_free"));
 
926
                filter_free.add_argument (new CCodeIdentifier ("filter"));
 
927
                new_block.add_statement (new CCodeExpressionStatement (filter_free));
 
928
 
 
929
                new_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("self")));
898
930
 
899
931
                member_decl_frag.append (proxy_new.copy ());
900
932
                proxy_new.block = new_block;
901
933
                source_type_member_definition.append (proxy_new);
902
934
 
 
935
                generate_proxy_filter_function (iface);
 
936
 
 
937
                // dbus proxy dispose
 
938
                var proxy_dispose = new CCodeFunction (lower_cname + "_dispose", "void");
 
939
                proxy_dispose.add_parameter (new CCodeFormalParameter ("self", "GObject*"));
 
940
                proxy_dispose.modifiers = CCodeModifiers.STATIC;
 
941
                proxy_dispose.block = new CCodeBlock ();
 
942
 
 
943
                cdecl = new CCodeDeclaration ("DBusGConnection");
 
944
                cdecl.add_declarator (new CCodeVariableDeclarator ("*connection"));
 
945
                proxy_dispose.block.add_statement (cdecl);
 
946
 
 
947
                var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
 
948
                gconnection.add_argument (new CCodeIdentifier ("self"));
 
949
                gconnection.add_argument (new CCodeConstant ("\"connection\""));
 
950
                gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("connection")));
 
951
                gconnection.add_argument (new CCodeConstant ("NULL"));
 
952
                proxy_dispose.block.add_statement (new CCodeExpressionStatement (gconnection));
 
953
 
 
954
                // remove filter
 
955
                filter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_remove_filter"));
 
956
                filter_call.add_argument (raw_connection);
 
957
                filter_call.add_argument (new CCodeIdentifier (lower_cname + "_filter"));
 
958
                filter_call.add_argument (new CCodeIdentifier ("self"));
 
959
                proxy_dispose.block.add_statement (new CCodeExpressionStatement (filter_call));
 
960
 
 
961
                // chain up
 
962
                var parent_class = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
 
963
                parent_class.add_argument (new CCodeIdentifier (lower_cname + "_parent_class"));
 
964
                var chainup = new CCodeFunctionCall (new CCodeMemberAccess.pointer (parent_class, "dispose"));
 
965
                chainup.add_argument (new CCodeIdentifier ("self"));
 
966
                proxy_dispose.block.add_statement (new CCodeExpressionStatement (chainup));
 
967
 
 
968
                source_type_member_definition.append (proxy_dispose);
 
969
 
903
970
                var proxy_class_init = new CCodeFunction (lower_cname + "_class_init", "void");
904
971
                proxy_class_init.add_parameter (new CCodeFormalParameter ("klass", cname + "Class*"));
905
972
                proxy_class_init.modifiers = CCodeModifiers.STATIC;
906
973
                proxy_class_init.block = new CCodeBlock ();
 
974
                var gobject_class = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
 
975
                gobject_class.add_argument (new CCodeIdentifier ("klass"));
 
976
                proxy_class_init.block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (gobject_class, "dispose"), new CCodeIdentifier (lower_cname + "_dispose"))));
907
977
                source_type_member_definition.append (proxy_class_init);
908
978
 
909
979
                var proxy_instance_init = new CCodeFunction (lower_cname + "_init", "void");
934
1004
                source_type_member_definition.append (proxy_iface_init);
935
1005
        }
936
1006
 
 
1007
        void generate_proxy_filter_function (Interface iface) {
 
1008
                string lower_cname = iface.get_lower_case_cprefix () + "dbus_proxy";
 
1009
 
 
1010
                var proxy_filter = new CCodeFunction (lower_cname + "_filter", "DBusHandlerResult");
 
1011
                proxy_filter.add_parameter (new CCodeFormalParameter ("connection", "DBusConnection*"));
 
1012
                proxy_filter.add_parameter (new CCodeFormalParameter ("message", "DBusMessage*"));
 
1013
                proxy_filter.add_parameter (new CCodeFormalParameter ("user_data", "void*"));
 
1014
 
 
1015
                var filter_block = new CCodeBlock ();
 
1016
 
 
1017
                // only handle signals concering the object path
 
1018
                var path = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_path"));
 
1019
                path.add_argument (new CCodeIdentifier ("user_data"));
 
1020
 
 
1021
                var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_has_path"));
 
1022
                ccheck.add_argument (new CCodeIdentifier ("message"));
 
1023
                ccheck.add_argument (path);
 
1024
 
 
1025
                var object_filter_block = new CCodeBlock ();
 
1026
                filter_block.add_statement (new CCodeIfStatement (ccheck, object_filter_block));
 
1027
 
 
1028
                handle_signals (iface, object_filter_block);
 
1029
 
 
1030
                filter_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED")));
 
1031
 
 
1032
                source_type_member_declaration.append (proxy_filter.copy ());
 
1033
                proxy_filter.block = filter_block;
 
1034
                source_type_member_definition.append (proxy_filter);
 
1035
        }
 
1036
 
 
1037
        string generate_dbus_signal_handler (Signal sig, ObjectTypeSymbol sym) {
 
1038
                string wrapper_name = "_dbus_handle_%s_%s".printf (sym.get_lower_case_cname (), sig.get_cname ());
 
1039
 
 
1040
                // declaration
 
1041
 
 
1042
                CCodeDeclaration cdecl;
 
1043
 
 
1044
                var function = new CCodeFunction (wrapper_name, "void");
 
1045
                function.modifiers = CCodeModifiers.STATIC;
 
1046
 
 
1047
                function.add_parameter (new CCodeFormalParameter ("self", sym.get_cname () + "*"));
 
1048
                function.add_parameter (new CCodeFormalParameter ("connection", "DBusConnection*"));
 
1049
                function.add_parameter (new CCodeFormalParameter ("message", "DBusMessage*"));
 
1050
 
 
1051
                var block = new CCodeBlock ();
 
1052
                var prefragment = new CCodeFragment ();
 
1053
 
 
1054
                cdecl = new CCodeDeclaration ("DBusMessageIter");
 
1055
                cdecl.add_declarator (new CCodeVariableDeclarator ("iter"));
 
1056
                block.add_statement (cdecl);
 
1057
 
 
1058
                block.add_statement (prefragment);
 
1059
 
 
1060
                var message_signature = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_get_signature"));
 
1061
                message_signature.add_argument (new CCodeIdentifier ("message"));
 
1062
                var signature_check = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
 
1063
                signature_check.add_argument (message_signature);
 
1064
                var signature_error_block = new CCodeBlock ();
 
1065
                signature_error_block.add_statement (new CCodeReturnStatement ());
 
1066
                prefragment.append (new CCodeIfStatement (signature_check, signature_error_block));
 
1067
 
 
1068
                var iter_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_iter_init"));
 
1069
                iter_call.add_argument (new CCodeIdentifier ("message"));
 
1070
                iter_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter")));
 
1071
                prefragment.append (new CCodeExpressionStatement (iter_call));
 
1072
 
 
1073
                var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
 
1074
                ccall.add_argument (new CCodeIdentifier ("self"));
 
1075
                ccall.add_argument (sig.get_canonical_cconstant ());
 
1076
 
 
1077
                // expected type signature for input parameters
 
1078
                string type_signature = "";
 
1079
 
 
1080
                foreach (FormalParameter param in sig.get_parameters ()) {
 
1081
                        cdecl = new CCodeDeclaration (param.parameter_type.get_cname ());
 
1082
                        cdecl.add_declarator (new CCodeVariableDeclarator (param.name, default_value_for_type (param.parameter_type, true)));
 
1083
                        prefragment.append (cdecl);
 
1084
 
 
1085
                        if (param.parameter_type.get_type_signature () == null) {
 
1086
                                Report.error (param.parameter_type.source_reference, "D-Bus serialization of type `%s' is not supported".printf (param.parameter_type.to_string ()));
 
1087
                                continue;
 
1088
                        }
 
1089
 
 
1090
                        var st = param.parameter_type.data_type as Struct;
 
1091
                        if (st != null && !st.is_simple_type ()) {
 
1092
                                ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
 
1093
                        } else {
 
1094
                                ccall.add_argument (new CCodeIdentifier (param.name));
 
1095
                        }
 
1096
 
 
1097
                        if (param.parameter_type is ArrayType) {
 
1098
                                var array_type = (ArrayType) param.parameter_type;
 
1099
 
 
1100
                                for (int dim = 1; dim <= array_type.rank; dim++) {
 
1101
                                        string length_cname = get_array_length_cname (param.name, dim);
 
1102
 
 
1103
                                        cdecl = new CCodeDeclaration ("int");
 
1104
                                        cdecl.add_declarator (new CCodeVariableDeclarator (length_cname, new CCodeConstant ("0")));
 
1105
                                        prefragment.append (cdecl);
 
1106
                                        ccall.add_argument (new CCodeIdentifier (length_cname));
 
1107
                                }
 
1108
                        }
 
1109
 
 
1110
                        type_signature += param.parameter_type.get_type_signature ();
 
1111
 
 
1112
                        var target = new CCodeIdentifier (param.name);
 
1113
                        var expr = read_expression (prefragment, param.parameter_type, new CCodeIdentifier ("iter"), target);
 
1114
                        prefragment.append (new CCodeExpressionStatement (new CCodeAssignment (target, expr)));
 
1115
                }
 
1116
 
 
1117
                signature_check.add_argument (new CCodeConstant ("\"%s\"".printf (type_signature)));
 
1118
 
 
1119
                block.add_statement (new CCodeExpressionStatement (ccall));
 
1120
 
 
1121
                cdecl = new CCodeDeclaration ("DBusMessage*");
 
1122
                cdecl.add_declarator (new CCodeVariableDeclarator ("reply"));
 
1123
                block.add_statement (cdecl);
 
1124
 
 
1125
                source_type_member_declaration.append (function.copy ());
 
1126
 
 
1127
                function.block = block;
 
1128
                source_type_member_definition.append (function);
 
1129
 
 
1130
                return wrapper_name;
 
1131
        }
 
1132
 
 
1133
        void handle_signal (string dbus_iface_name, string dbus_signal_name, string handler_name, CCodeBlock block, ref CCodeIfStatement clastif) {
 
1134
                var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_is_signal"));
 
1135
                ccheck.add_argument (new CCodeIdentifier ("message"));
 
1136
                ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name)));
 
1137
                ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_signal_name)));
 
1138
 
 
1139
                var callblock = new CCodeBlock ();
 
1140
 
 
1141
                var ccall = new CCodeFunctionCall (new CCodeIdentifier (handler_name));
 
1142
                ccall.add_argument (new CCodeIdentifier ("user_data"));
 
1143
                ccall.add_argument (new CCodeIdentifier ("connection"));
 
1144
                ccall.add_argument (new CCodeIdentifier ("message"));
 
1145
 
 
1146
                callblock.add_statement (new CCodeExpressionStatement (ccall));
 
1147
 
 
1148
                var cif = new CCodeIfStatement (ccheck, callblock);
 
1149
                if (clastif == null) {
 
1150
                        block.add_statement (cif);
 
1151
                } else {
 
1152
                        clastif.false_statement = cif;
 
1153
                }
 
1154
 
 
1155
                clastif = cif;
 
1156
        }
 
1157
 
 
1158
        void handle_signals (Interface iface, CCodeBlock block) {
 
1159
                string dbus_iface_name = iface.get_attribute ("DBus").get_string ("name");
 
1160
 
 
1161
                CCodeIfStatement clastif = null;
 
1162
                foreach (Signal sig in iface.get_signals ()) {
 
1163
                        if (sig.access != SymbolAccessibility.PUBLIC) {
 
1164
                                continue;
 
1165
                        }
 
1166
 
 
1167
                        handle_signal (dbus_iface_name, Symbol.lower_case_to_camel_case (sig.name), generate_dbus_signal_handler (sig, iface), block, ref clastif);
 
1168
                }
 
1169
        }
 
1170
 
937
1171
        void generate_marshalling (Method m, string dbus_iface_name, CCodeFragment prefragment, CCodeFragment postfragment) {
938
1172
                CCodeDeclaration cdecl;
939
1173
 
1039
1273
 
1040
1274
                CCodeDeclaration cdecl;
1041
1275
 
1042
 
                var function = new CCodeFunction (proxy_name, m.return_type.get_cname ());
 
1276
                var function = new CCodeFunction (proxy_name);
1043
1277
                function.modifiers = CCodeModifiers.STATIC;
1044
1278
 
1045
1279
                var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
1046
1280
 
1047
 
                generate_cparameters (m, m.return_type, false, cparam_map, function);
 
1281
                generate_cparameters (m, cparam_map, function);
1048
1282
 
1049
1283
                var block = new CCodeBlock ();
1050
1284
                var prefragment = new CCodeFragment ();
1140
1374
                cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("callback", "GAsyncReadyCallback"));
1141
1375
                cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("user_data", "gpointer"));
1142
1376
 
1143
 
                generate_cparameters (m, m.return_type, false, cparam_map, function, null, null, null, 1);
 
1377
                generate_cparameters (m, cparam_map, function, null, null, null, 1);
1144
1378
 
1145
1379
                var block = new CCodeBlock ();
1146
1380
                var prefragment = new CCodeFragment ();
1261
1495
 
1262
1496
                CCodeDeclaration cdecl;
1263
1497
 
1264
 
                var function = new CCodeFunction (proxy_name, m.return_type.get_cname ());
 
1498
                var function = new CCodeFunction (proxy_name);
1265
1499
                function.modifiers = CCodeModifiers.STATIC;
1266
1500
 
1267
1501
                var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
1268
1502
 
1269
1503
                cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("res", "GAsyncResult*"));
1270
1504
 
1271
 
                generate_cparameters (m, m.return_type, false, cparam_map, function, null, null, null, 2);
 
1505
                generate_cparameters (m, cparam_map, function, null, null, null, 2);
1272
1506
 
1273
1507
                var block = new CCodeBlock ();
1274
1508
                var prefragment = new CCodeFragment ();