This file is indexed.

/usr/include/mapper-0/mapper/mapper.h is in libmapper-dev 0.3~git+20141027-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   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
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
#ifndef __MAPPER_H__
#define __MAPPER_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <mapper/mapper_db.h>
#include <mapper/mapper_types.h>

#define MAPPER_NOW ((mapper_timetag_t){0L,1L})

/*! \mainpage libmapper

This is the API documentation for libmapper, a network-based signal
mapping framework.  Please see the Modules section for detailed
information, and be sure to consult the tutorial to get started with
libmapper concepts.

 */

/*** Signals ***/

/*! @defgroup signals Signals

    @{ Signals define inputs or outputs for devices.  A signal
       consists of a scalar or vector value of some integer or
       floating-point type.  A mapper_signal is created by adding an
       input or output to a device.  It can optionally be provided
       with some metadata such as a signal's range, unit, or other
       properties.  Signals can be mapped between linked devices
       anywhere on the network by creating connections through a
       GUI. */

struct _mapper_signal;
typedef struct _mapper_signal *mapper_signal;
struct _mapper_connection;

/*! The set of possible actions on an instance, used to register callbacks
 *  to inform them of what is happening. */
typedef enum {
    IN_NEW                  = 0x01, //!< New instance has been created.
    IN_UPSTREAM_RELEASE     = 0x02, //!< Instance has been released by upstream device.
    IN_DOWNSTREAM_RELEASE   = 0x04, //!< Instance has been released by downstream device.
    IN_OVERFLOW             = 0x08, //!< No local instances left for incoming remote instance.
    IN_ALL                  = 0xFF
} msig_instance_event_t;

/*! A signal handler function can be called whenever a signal value
 *  changes. */
typedef void mapper_signal_update_handler(mapper_signal msig,
                                          mapper_db_signal props,
                                          int instance_id,
                                          void *value,
                                          int count,
                                          mapper_timetag_t *tt);

/*! A handler function to be called whenever a signal instance management
 *  event occurs. */
typedef void mapper_signal_instance_event_handler(mapper_signal msig,
                                                  mapper_db_signal props,
                                                  int instance_id,
                                                  msig_instance_event_t event,
                                                  mapper_timetag_t *tt);

/*! Update the value of a signal.
 *  The signal will be routed according to external requests.
 *  \param sig      The signal to update.
 *  \param value    A pointer to a new value for this signal.  If the
 *                  signal type is 'i', this should be int*; if the signal type
 *                  is 'f', this should be float*.  It should be an array at
 *                  least as long as the signal's length property.
 *  \param count    The number of instances of the value that are being
 *                  updated.  For non-periodic signals, this should be 0
 *                  or 1.  For periodic signals, this may indicate that a
 *                  block of values should be accepted, where the last
 *                  value is the current value.
 *  \param timetag  The time at which the value update was aquired. If
 *                  the value is MAPPER_NOW, libmapper will tag the
 *                  value update with the current time. See
 *                  mdev_start_queue() for more information on
 *                  bundling multiple signal updates with the same
 *                  timetag. */
void msig_update(mapper_signal sig, void *value,
                 int count, mapper_timetag_t timetag);

/*! Update the value of a scalar signal of type int.
 *  This is a scalar equivalent to msig_update(), for when passing by
 *  value is more convenient than passing a pointer.
 *  The signal will be routed according to external requests.
 *  \param sig   The signal to update.
 *  \param value A new scalar value for this signal. */
void msig_update_int(mapper_signal sig, int value);

/*! Update the value of a scalar signal of type float.
 *  This is a scalar equivalent to msig_update(), for when passing by
 *  value is more convenient than passing a pointer.
 *  The signal will be routed according to external requests.
 *  \param sig The signal to update.
 *  \param value A new scalar value for this signal. */
void msig_update_float(mapper_signal sig, float value);

/*! Update the value of a scalar signal of type double.
 *  This is a scalar equivalent to msig_update(), for when passing by
 *  value is more convenient than passing a pointer.
 *  The signal will be routed according to external requests.
 *  \param sig The signal to update.
 *  \param value A new scalar value for this signal. */
void msig_update_double(mapper_signal sig, double value);

/*! Get a signal's value.
 *  \param sig      The signal to operate on.
 *  \param timetag  A location to receive the value's time tag.
 *                  May be 0.
 *  \return         A pointer to an array containing the value
 *                  of the signal, or 0 if the signal has no value. */
void *msig_value(mapper_signal sig, mapper_timetag_t *timetag);

/*! Query the values of any signals connected via mapping connections.
 *  \param sig      A local output signal. We will be querying the remote
 *                  ends of this signal's mapping connections.
 *  \param tt       A timetag to be attached to the outgoing query. Query
 *                  responses should also be tagged with this time.
 *  \return The number of queries sent, or -1 for error. */
int msig_query_remotes(mapper_signal sig, mapper_timetag_t tt);

/**** Instances ****/

/*! Add new instances to the reserve list. Note that if instance ids are specified,
 *  libmapper will not add multiple instances with the same id.
 *  \param sig          The signal to which the instances will be added.
 *  \param num          The number of instances to add.
 *  \param ids          Array of integer ids, one for each new instance,
 *                      or 0 for automatically-generated instance ids.
 *  \param user_data    Array of user context pointers, one for each new instance,
 *                      or 0 if not needed.
 *  \return             Number of instances added. */
int msig_reserve_instances(mapper_signal sig, int num, int *ids, void **user_data);

/*! Update the value of a specific signal instance.
 *  The signal will be routed according to external requests.
 *  \param sig          The signal to operate on.
 *  \param instance_id  The instance to update.
 *  \param value        A pointer to a new value for this signal.  If the
 *                      signal type is 'i', this should be int*; if the signal type
 *                      is 'f', this should be float*.  It should be an array at
 *                      least as long as the signal's length property.
 *  \param count        The number of values being updated, or 0 for
 *                      non-periodic signals.
 *  \param timetag      The time at which the value update was aquired. If NULL,
 *                      libmapper will tag the value update with the current
 *                      time. See mdev_start_queue() for more information on
 *                      bundling multiple signal updates with the same timetag. */
void msig_update_instance(mapper_signal sig, int instance_id, void *value,
                          int count, mapper_timetag_t timetag);

/*! Release a specific instance of a signal by removing it from the list
 *  of active instances and adding it to the reserve list.
 *  \param sig         The signal to operate on.
 *  \param instance_id The instance to suspend.
 *  \param timetag     The time at which the instance was released; if NULL,
 *                     will be tagged with the current time.
 *                     See mdev_start_queue() for more information on
 *                     bundling multiple signal updates with the same timetag. */
void msig_release_instance(mapper_signal sig, int instance_id,
                           mapper_timetag_t timetag);

/*! Remove a specific instance of a signal and free its memory.
 *  \param sig         The signal to operate on.
 *  \param instance_id The instance to suspend. */
void msig_remove_instance(mapper_signal sig, int instance_id);

/*! Get the local id of the oldest active instance.
 *  \param sig         The signal to operate on.
 *  \param instance_id A location to receive the instance id.
 *  \return            Zero if an instance id has been found, non-zero otherwise. */
int msig_get_oldest_active_instance(mapper_signal sig, int *instance_id);

/*! Get the local id of the newest active instance.
 *  \param sig         The signal to operate on.
 *  \param instance_id A location to receive the instance id.
 *  \return            Zero if an instance id has been found, non-zero otherwise. */
int msig_get_newest_active_instance(mapper_signal sig, int *instance_id);

/*! Get a signal_instance's value.
 *  \param sig         The signal to operate on.
 *  \param instance_id The instance to operate on.
 *  \param timetag     A location to receive the value's time tag.
 *                     May be 0.
 *  \return            A pointer to an array containing the value
 *                     of the signal instance, or 0 if the signal instance
 *                     has no value. */
void *msig_instance_value(mapper_signal sig, int instance_id,
                          mapper_timetag_t *timetag);

/*! Copy group/routing data for sharing an instance abstraction
 *  between multiple signals.
 *  \param from         The signal to copy from.
 *  \param to           The signal to copy to.
 *  \param instance_id  The instance to copy. */
void msig_match_instances(mapper_signal from, mapper_signal to, int instance_id);

/*! Return the number of active instances owned by a signal.
 *  \param  sig The signal to query.
 *  \return     The number of active instances. */
int msig_num_active_instances(mapper_signal sig);

/*! Return the number of reserved instances owned by a signal.
 *  \param  sig The signal to query.
 *  \return     The number of active instances. */
int msig_num_reserved_instances(mapper_signal sig);

/*! Get an active signal instance's ID by its index.  Intended to be
 * used for iterating over the active instances.
 *  \param sig    The signal to operate on.
 *  \param index  The numerical index of the ID to retrieve.  Shall be
 *                between zero and the return value of
 *                msig_num_active_instances().
 *  \return       The instance ID associated with the given index. */
int msig_active_instance_id(mapper_signal sig, int index);

/*! Set the allocation method to be used when a previously-unseen
 *  instance ID is received.
 *  \param sig  The signal to operate on.
 *  \param mode Method to use for adding or reallocating active instances
 *              if no reserved instances are available. */
void msig_set_instance_allocation_mode(mapper_signal sig,
                                       mapper_instance_allocation_type mode);

/*! Get the allocation method to be used when a previously-unseen
 *  instance ID is received.
 *  \param sig  The signal to operate on.
 *  \return     The allocation mode of the provided signal. */
mapper_instance_allocation_type msig_get_instance_allocation_mode(mapper_signal sig);

/*! Set the handler to be called on signal instance management events.
 *  \param sig          The signal to operate on.
 *  \param h            A handler function for processing instance managment events.
 *  \param flags        Bitflags for indicating the types of events which should
 *                      trigger the callback. Can be a combination of IN_NEW,
 *                      IN_UPSTREAM_RELEASE, IN_DOWNSTREAM_RELEASE, and IN_OVERFLOW.
 *  \param user_data    User context pointer to be passed to handler. */
void msig_set_instance_event_callback(mapper_signal sig,
                                      mapper_signal_instance_event_handler h,
                                      int flags, void *user_data);

/*! Associate a signal instance with an arbitrary pointer.
 *  \param sig          The signal to operate on.
 *  \param instance_id  The instance to operate on.
 *  \param user_data    A pointer to user data to be associated
 *                      with this instance. */
void msig_set_instance_data(mapper_signal sig, int instance_id,
                            void *user_data);

/*! Retrieve the arbitrary pointer associated with a signal instance.
 *  \param sig          The signal to operate on.
 *  \param instance_id  The instance to operate on.
 *  \return             A pointer associated with this instance. */
void *msig_get_instance_data(mapper_signal sig, int instance_id);

/*! Set or unset the message handler for a signal.
 *  \param sig       The signal to operate on.
 *  \param handler   A pointer to a mapper_signal_update_handler
 *                   function for processing incoming messages.
 *  \param user_data User context pointer to be passed to handler. */
void msig_set_callback(mapper_signal sig,
                       mapper_signal_update_handler *handler,
                       void *user_data);

/*! Get the number of connections attatched to a specific signal.
 *  \param sig      The signal to check.
 *  \return         The number of attached connections. */
int msig_num_connections(mapper_signal sig);

/**** Signal properties ****/

/*! Get the full OSC name of a signal, including device name
 *  prefix.
 *  \param sig  The signal value to query.
 *  \param name A string to accept the name.
 *  \param len  The length of string pointed to by name.
 *  \return The number of characters used, or 0 if error.  Note that
 *          in some cases the name may not be available. */
int msig_full_name(mapper_signal sig, char *name, int len);

/*! Set or remove the minimum of a signal.
 *  \param sig      The signal to operate on.
 *  \param minimum  Must be the same type as the signal, or 0 to remove
 *                  the minimum. */
void msig_set_minimum(mapper_signal sig, void *minimum);

/*! Set or remove the maximum of a signal.
 *  \param sig      The signal to operate on.
 *  \param maximum  Must be the same type as the signal, or 0 to remove
 *                  the maximum. */
void msig_set_maximum(mapper_signal sig, void *maximum);

/*! Set the rate of a signal.
 *  \param sig      The signal to operate on.
 *  \param rate     A rate for this signal in samples/second, or zero
 *                  for non-periodic signals. */
void msig_set_rate(mapper_signal sig, float rate);

/*! Get a signal's property structure.
 *  \param sig  The signal to operate on.
 *  \return     A structure containing the signal's properties. */
mapper_db_signal msig_properties(mapper_signal sig);

/*! Set a property of a signal.  Can be used to provide arbitrary
 *  metadata.  Value pointed to will be copied.
 *  \param sig       The signal to operate on.
 *  \param property  The name of the property to add.
 *  \param type      The property  datatype.
 *  \param value     An array of property values.
 *  \param length    The length of value array. */
void msig_set_property(mapper_signal sig, const char *property,
                       char type, void *value, int length);

/*! Remove a property of a signal.
 *  \param sig       The signal to operate on.
 *  \param property  The name of the property to remove. */
void msig_remove_property(mapper_signal sig, const char *property);

/* @} */

/*** Devices ***/

/*! @defgroup devices Devices

    @{ A device is an entity on the network which has input and/or
       output signals.  The mapper_device is the primary interface
       through which a program uses libmapper.  A device must have a
       name, to which a unique ordinal is subsequently appended.  It
       can also be given other user-specified metadata.  Devices must
       be linked before their signals can be connected, which is
       accomplished by requests from an external GUI. */

/*! Allocate and initialize a mapper device.
 *  \param name_prefix  A short descriptive string to identify the device.
 *  \param port         An optional port for starting the port allocation
 *                      scheme.
 *  \param admin        A previously allocated admin to use.  If 0, an
 *                      admin will be allocated for use with this device.
 *  \return             A newly allocated mapper device.  Should be free
 *                      using mdev_free(). */
mapper_device mdev_new(const char *name_prefix, int port, mapper_admin admin);

//! Free resources used by a mapper device.
void mdev_free(mapper_device dev);

/*! Add an input signal to a mapper device.  Values and strings
 *  pointed to by this call (except user_data) will be copied.
 *  For minimum and maximum, actual type must correspond to 'type'.
 *  If type='i', then int*; if type='f', then float*.
 *  \param dev     The device to add a signal to.
 *  \param name    The name of the signal.
 *  \param length  The length of the signal vector, or 1 for a scalar.
 *  \param type    The type fo the signal value.
 *  \param unit    The unit of the signal, or 0 for none.
 *  \param minimum Pointer to a minimum value, or 0 for none.
 *  \param maximum Pointer to a maximum value, or 0 for none.
 *  \param handler Function to be called when the value of the
 *                 signal is updated.
 *  \param user_data User context pointer to be passed to handler. */
mapper_signal mdev_add_input(mapper_device dev, const char *name,
                             int length, char type, const char *unit,
                             void *minimum, void *maximum,
                             mapper_signal_update_handler *handler,
                             void *user_data);

/*! Add an input signal with multiple instances to a mapper device.
 *  Values and strings pointed to by this call (except user_data) will be copied.
 *  For minimum and maximum, actual type must correspond to 'type'.
 *  If type='i', then int*; if type='f', then float*.
 *  \param dev           The device to add a signal to.
 *  \param name          The name of the signal.
 *  \param length        The length of the signal vector, or 1 for a scalar.
 *  \param type          The type fo the signal value.
 *  \param unit          The unit of the signal, or 0 for none.
 *  \param minimum       Pointer to a minimum value, or 0 for none.
 *  \param maximum       Pointer to a maximum value, or 0 for none.
 *  \param num_instances Number of instances to reserve.
 *  \param handler       Function to be called when the value of the
 *                       signal is updated.
 *  \param user_data     User context pointer to be passed to handler. */
mapper_signal mdev_add_poly_input(mapper_device dev, const char *name,
                                  int length, char type, const char *unit,
                                  void *minimum, void *maximum,
                                  int num_instances,
                                  mapper_signal_update_handler *handler,
                                  void *user_data);

/*! Add an output signal to a mapper device.  Values and strings
 *  pointed to by this call (except user_data) will be copied.
 *  For minimum and maximum, actual type must correspond to 'type'.
 *  If type='i', then int*; if type='f', then float*.
 *  \param dev     The device to add a signal to.
 *  \param name    The name of the signal.
 *  \param length  The length of the signal vector, or 1 for a scalar.
 *  \param type    The type fo the signal value.
 *  \param unit    The unit of the signal, or 0 for none.
 *  \param minimum Pointer to a minimum value, or 0 for none.
 *  \param maximum Pointer to a maximum value, or 0 for none. */
mapper_signal mdev_add_output(mapper_device dev, const char *name,
                              int length, char type, const char *unit,
                              void *minimum, void *maximum);

/*! Add an output signal with multiple instances to a mapper device.
 *  Values and strings pointed to by this call (except user_data) will be copied.
 *  For minimum and maximum, actual type must correspond to 'type'.
 *  If type='i', then int*; if type='f', then float*.
 *  \param dev     The device to add a signal to.
 *  \param name    The name of the signal.
 *  \param length  The length of the signal vector, or 1 for a scalar.
 *  \param type    The type fo the signal value.
 *  \param unit    The unit of the signal, or 0 for none.
 *  \param num_instances Number of instances to reserve.
 *  \param minimum Pointer to a minimum value, or 0 for none.
 *  \param maximum Pointer to a maximum value, or 0 for none. */
mapper_signal mdev_add_poly_output(mapper_device dev, const char *name,
                                   int length, char type, const char *unit,
                                   void *minimum, void *maximum,
                                   int num_instances);

/* Remove a device's input signal.
 * \param dev The device to remove a signal from.
 * \param sig The signal to remove. */
void mdev_remove_input(mapper_device dev, mapper_signal sig);

/* Remove a device's output signal.
 * \param dev The device to remove a signal from.
 * \param sig The signal to remove. */
void mdev_remove_output(mapper_device dev, mapper_signal sig);

//! Return the number of inputs.
int mdev_num_inputs(mapper_device dev);

//! Return the number of outputs.
int mdev_num_outputs(mapper_device dev);

//! Return the number of incoming links.
int mdev_num_links_in(mapper_device dev);

//! Return the number of outgoing links.
int mdev_num_links_out(mapper_device dev);

//! Return the number of incoming connections.
int mdev_num_connections_in(mapper_device dev);

//! Return the number of outgoing connections.
int mdev_num_connections_out(mapper_device dev);

/*! Get input signals.
 *  \param dev Device to search in.
 *  \return Pointer to the linked list of input mapper_signals, or zero
 *          if not found.
 */
mapper_signal *mdev_get_inputs(mapper_device dev);

/*! Get output signals.
 *  \param dev Device to search in.
 *  \return Pointer to the linked list of output mapper_signals, or zero
 *          if not found.
 */
mapper_signal *mdev_get_outputs(mapper_device dev);

/*! Get an input signal with a given name.
 *  \param dev   Device to search in.
 *  \param name  Name of input signal to search for. It may optionally
 *               begin with a '/' character.
 *  \param index Optional place to receive the index of the matching signal.
 *  \return Pointer to the mapper_signal describing the signal, or zero
 *          if not found.
 */
mapper_signal mdev_get_input_by_name(mapper_device dev, const char *name,
                                     int *index);

/*! Get an output signal with a given name.
 *  \param dev   Device to search in.
 *  \param name  Name of output signal to search for. It may optionally
 *               begin with a '/' character.
 *  \param index Optional place to receive the index of the matching signal.
 *  \return Pointer to the mapper_signal describing the signal, or zero
 *          if not found.
 */
mapper_signal mdev_get_output_by_name(mapper_device dev, const char *name,
                                      int *index);

/* Get an input signal with the given index.
 * \param dev   The device to search in.
 * \param index Index of the signal to retrieve.
 * \return Pointer to the mapper_signal describing the signal, or zero
 *         if not found. */
mapper_signal mdev_get_input_by_index(mapper_device dev, int index);

/* Get an output signal with the given index.
 * \param dev   The device to search in.
 * \param index Index of the signal to retrieve.
 * \return Pointer to the mapper_signal describing the signal, or zero
 *         if not found. */
mapper_signal mdev_get_output_by_index(mapper_device dev, int index);

/*! Get a device's property structure.
 *  \param dev  The device to operate on.
 *  \return     A structure containing the device's properties. */
mapper_db_device mdev_properties(mapper_device dev);

/*! Set a property of a device.  Can be used to provide arbitrary
 *  metadata.  Value pointed to will be copied.
 *  \param dev       The device to operate on.
 *  \param property  The name of the property to add.
 *  \param type      The property  datatype.
 *  \param value     An array of property values.
 *  \param length    The length of value array. */
void mdev_set_property(mapper_device dev, const char *property,
                       char type, void *value, int length);

/*! Remove a property of a device.
 *  \param dev       The device to operate on.
 *  \param property  The name of the property to remove. */
void mdev_remove_property(mapper_device dev, const char *property);

/*! Poll this device for new messages.
 *  Note, if you have multiple devices, the right thing to do is call
 *  this function for each of them with block_ms=0, and add your own
 *  sleep if necessary.
 *  \param dev      The device to check messages for.
 *  \param block_ms Number of milliseconds to block waiting for
 *                  messages, or 0 for non-blocking behaviour.
 *  \return The number of handled messages. May be zero if there was
 *          nothing to do. */
int mdev_poll(mapper_device dev, int block_ms);

/*! Return the number of file descriptors needed for this device.
 *  This can be used to allocated an appropriately-sized list for
 *  called to mdev_get_fds.  Note that the number of descriptors
 *  needed can change throughout the life of a device, therefore this
 *  function should be called whenever the list of file descriptors is
 *  needed.
 *  \param md The device to count file descriptors for.
 *  \return The number of file descriptors needed for the indicated
 *          device. */
int mdev_num_fds(mapper_device md);

/*! Write the list of file descriptors for this device to the provided
 *  array.  Up to num file descriptors will be written.  These file
 *  descriptors can be used as input for the read array of select or
 *  poll, for example.
 *  \param md  The device to get file descriptors for.
 *  \param fds Memory to receive file descriptors.
 *  \param num The number of file descriptors pointed to by fds.
 *  \return The number of file descriptors actually written to fds. */
int mdev_get_fds(mapper_device md, int *fds, int num);

/*! If an external event indicates that a file descriptor for this
 *  device needs servicing, this function should be called.
 *  \param md The device that needs servicing.
 *  \param fd The file descriptor that needs servicing. */
void mdev_service_fd(mapper_device md, int fd);

/*! Detect whether a device is completely initialized.
 *  \return Non-zero if device is completely initialized, i.e., has an
 *  allocated receiving port and unique network name.  Zero
 *  otherwise. */
int mdev_ready(mapper_device dev);

/*! Return a string indicating the device's full name, if it is
 *  registered.  The returned string must not be externally modified.
 *  \param dev The device to query.
 *  \return String containing the device's full name, or zero if it is
 *  not available. */
const char *mdev_name(mapper_device dev);

/*! Return the unique ID allocated to this device by the mapper network.
 *  \param dev The device to query.
 *  \return An integer indicating the device's ID, or zero if it is
 *  not available. */
unsigned int mdev_id(mapper_device dev);

/*! Return the port used by a device to receive signals, if available.
 *  \param dev The device to query.
 *  \return An integer indicating the device's port, or zero if it is
 *  not available. */
unsigned int mdev_port(mapper_device dev);

/*! Return the IPv4 address used by a device to receive signals, if available.
 *  \param dev The device to query.
 *  \return A pointer to an in_addr struct indicating the device's IP
 *          address, or zero if it is not available.  In general this
 *          will be the IPv4 address associated with the selected
 *          local network interface.
 */
const struct in_addr *mdev_ip4(mapper_device dev);

/*! Return a string indicating the name of the network interface this
 *  device is listening on.
 *  \param dev The device to query.
 *  \return A string containing the name of the network interface. */
const char *mdev_interface(mapper_device dev);

/*! Return an allocated ordinal which is appended to this device's
 *  network name.  In general the results of this function are not
 *  valid unless mdev_ready() returns non-zero.
 *  \param dev The device to query.
 *  \return A positive ordinal unique to this device (per name). */
unsigned int mdev_ordinal(mapper_device dev);

/*! Start a time-tagged mapper queue. */
void mdev_start_queue(mapper_device md, mapper_timetag_t tt);

/*! Dispatch a time-tagged mapper queue. */
void mdev_send_queue(mapper_device md, mapper_timetag_t tt);

/*! Get access to the device's underlying lo_server. */
lo_server mdev_get_lo_server(mapper_device md);

/*! Get the device's synchronization clock offset. */
double mdev_get_clock_offset(mapper_device md);

/*! The set of possible actions on a local device link or
 *  connection. */
typedef enum {
    MDEV_LOCAL_ESTABLISHED,
    MDEV_LOCAL_MODIFIED,
    MDEV_LOCAL_DESTROYED,
} mapper_device_local_action_t;

/*! Function to call when a local device link is established or
 *  destroyed. */
typedef void mapper_device_link_handler(mapper_device dev,
                                        mapper_db_link link,
                                        mapper_device_local_action_t action,
                                        void *user);

/*! Function to call when a local device connection is established or
 *  destroyed. */
typedef void mapper_device_connection_handler(mapper_device dev,
                                              mapper_db_link link,
                                              mapper_signal sig,
                                              mapper_db_connection connection,
                                              mapper_device_local_action_t action,
                                              void *user);

/*! Set a function to be called when a local device link is
 *  established or destroyed, indicated by the action parameter to the
 *  provided function. */
void mdev_set_link_callback(mapper_device dev,
                            mapper_device_link_handler *h, void *user);

/*! Set a function to be called when a local device connection is
 *  established or destroyed, indicated by the action parameter to the
 *  provided function. Important: if a link is destroyed, this
 *  function will not be called for all connections in the link. */
void mdev_set_connection_callback(mapper_device dev,
                                  mapper_device_connection_handler *h,
                                  void *user);

/* @} */

/*** Admins ***/

/*! @defgroup admins Admins

    @{ Admins handle the traffic on the multicast admin bus.  In
       general, you do not need to worry about this interface, as an
       admin will be created automatically when allocating a device.
       An admin only needs to be explicitly created if you plan to
       override default settings for the admin bus.  */

/*! Create an admin with custom parameters.  Creating an admin object
 *  manually is only required if you wish to specify custom network
 *  parameters.  Creating a device or monitor without specifying an
 *  admin will give you an object working on the "standard"
 *  configuration.
 * \param iface  If non-zero, a string identifying a preferred network
 *               interface.  This string can be enumerated e.g. using
 *               if_nameindex(). If zero, an interface will be
 *               selected automatically.
 * \param group  If non-zero, specify a multicast group address to use.
 *               Zero indicates that the standard group 224.0.1.3 should
 *               be used.
 * \param port   If non-zero, specify a multicast port to use.  Zero
 *               indicates that the standard port 7570 should be used.
 * \return       A newly allocated admin.  Should be freed using
 *               mapper_admin_free() */
mapper_admin mapper_admin_new(const char *iface, const char *group, int port);

/*! Free an admin created with mapper_admin_new(). */
void mapper_admin_free(mapper_admin admin);

/*! Get the version of libmapper */
const char *mapper_admin_libversion(mapper_admin admin);

/* @} */

/**** Device database ****/

/*! The set of possible actions on a database record, used
 *  to inform callbacks of what is happening to a record. */
typedef enum {
    MDB_MODIFY,
    MDB_NEW,
    MDB_REMOVE,
    MDB_UNRESPONSIVE,
} mapper_db_action_t;

/***** Devices *****/

/*! @defgroup devicedb Device database

    @{ A monitor may query information about devices on the network
       through this interface. */

/*! A callback function prototype for when a device record is added or
 *  updated in the database. Such a function is passed in to
 *  mapper_db_add_device_callback().
 *  \param record  Pointer to the device record.
 *  \param action  A value of mapper_db_action_t indicating what
 *                 is happening to the database record.
 *  \param user    The user context pointer registered with this
 *                 callback. */
typedef void mapper_db_device_handler(mapper_db_device record,
                                      mapper_db_action_t action,
                                      void *user);

/*! Register a callback for when a device record is added or updated
 *  in the database.
 *  \param db   The database to query.
 *  \param h    Callback function.
 *  \param user A user-defined pointer to be passed to the callback
 *              for context . */
void mapper_db_add_device_callback(mapper_db db,
                                   mapper_db_device_handler *h,
                                   void *user);

/*! Remove a device record callback from the database service.
 *  \param db   The database to query.
 *  \param h    Callback function.
 *  \param user The user context pointer that was originally specified
 *              when adding the callback. */
void mapper_db_remove_device_callback(mapper_db db,
                                      mapper_db_device_handler *h,
                                      void *user);

/*! Return the whole list of devices.
 *  \param db   The database to query.
 *  \return A double-pointer to the first item in the list of devices,
 *          or zero if none.  Use mapper_db_device_next() to
 *          iterate. */
mapper_db_device_t **mapper_db_get_all_devices(mapper_db db);

/*! Find information for a registered device.
 *  \param db          The database to query.
 *  \param device_name Name of the device to find in the database.
 *  \return            Information about the device, or zero if not found. */
mapper_db_device mapper_db_get_device_by_name(mapper_db db,
                                              const char *device_name);

/*! Look up information for a registered device using a hash of its name.
 *  \param db          The database to query.
 *  \param name_hash   CRC-32 name hash of the device to find in the database.
 *  \return            Information about the device, or zero if not found. */
mapper_db_device mapper_db_get_device_by_name_hash(mapper_db db,
                                                   uint32_t name_hash);

/*! Return the list of devices with a substring in their name.
 *  \param db             The database to query.
 *  \param device_pattern The substring to search for.
 *  \return    A double-pointer to the first item in a list of matching
 *             devices.  Use mapper_db_device_next() to iterate. */
mapper_db_device_t **mapper_db_match_devices_by_name(mapper_db db,
                                                     const char *device_pattern);

/*! Given a device record pointer returned from a previous
 *  mapper_db_return_*() call, get the next item in the list.
 *  \param s The previous device record pointer.
 *  \return  A double-pointer to the next device record in the list, or
 *           zero if no more devices. */
mapper_db_device_t **mapper_db_device_next(mapper_db_device_t **s);

/*! Given a device record pointer returned from a previous
 *  mapper_db_get_*() call, indicate that we are done iterating.
 *  \param s The previous device record pointer. */
void mapper_db_device_done(mapper_db_device_t **s);


/*! Look up a device property by index. To iterate all properties,
 *  call this function from index=0, increasing until it returns zero.
 *  \param dev      The device to look at.
 *  \param index    Numerical index of a device property.
 *  \param property Address of a string pointer to receive the name of
 *                  indexed property.  May be zero.
 *  \param type     A pointer to a location to receive the type of the
 *                  property value. (Required.)
 *  \param value    A pointer to a location to receive the address of the
 *                  property's value. (Required.)
 *  \param length   A pointer to a location to receive the vector length of
 *                  the property value. (Required.)
 *  \return Zero if found, otherwise non-zero. */
int mapper_db_device_property_index(mapper_db_device dev, unsigned int index,
                                    const char **property, char *type,
                                    const void **value, int *length);

/*! Look up a device property by name.
 *  \param dev      The device to look at.
 *  \param property The name of the property to retrive.
 *  \param type     A pointer to a location to receive the type of the
 *                  property value. (Required.)
 *  \param value    A pointer to a location to receive the address of the
 *                  property's value. (Required.)
 *  \param length   A pointer to a location to receive the vector length of
 *                  the property value. (Required.)
 *  \return Zero if found, otherwise non-zero. */
int mapper_db_device_property_lookup(mapper_db_device dev,
                                     const char *property, char *type,
                                     const void **value, int *length);

/*! Helper for printing typed mapper_prop values.
 *  \param type     The value type.
 *  \param length   The vector length of the value.
 *  \param value    A pointer to the property value to print. */
void mapper_prop_pp(char type, int length, const void *value);

/* @} */

/***** Signals *****/

/*! @defgroup signaldb Signal database

    @{ A monitor may query information about signals on the network
       through this interface. It is also used by local signals to
       store property information. */

/*! A callback function prototype for when a signal record is added or
 *  updated in the database. Such a function is passed in to
 *  mapper_db_add_signal_callback().
 *  \param record  Pointer to the signal record.
 *  \param action  A value of mapper_db_action_t indicating what
 *                 is happening to the database record.
 *  \param user    The user context pointer registered with this
 *                 callback. */
typedef void mapper_db_signal_handler(mapper_db_signal record,
                                      mapper_db_action_t action,
                                      void *user);

/*! Register a callback for when a signal record is added or updated
 *  in the database.
 *  \param db   The database to query.
 *  \param h    Callback function.
 *  \param user A user-defined pointer to be passed to the callback
 *              for context . */
void mapper_db_add_signal_callback(mapper_db db,
                                   mapper_db_signal_handler *h,
                                   void *user);

/*! Remove a signal record callback from the database service.
 *  \param db   The database to query.
 *  \param h    Callback function.
 *  \param user The user context pointer that was originally specified
 *              when adding the callback. */
void mapper_db_remove_signal_callback(mapper_db db,
                                      mapper_db_signal_handler *h,
                                      void *user);

/*! Return the list of all known inputs across all devices.
 *  \param db   The database to query.
 *  \return A double-pointer to the first item in the list of results
 *          or zero if none.  Use mapper_db_signal_next() to iterate. */
mapper_db_signal_t **mapper_db_get_all_inputs(mapper_db db);

/*! Return the list of all known outputs across all devices.
 *  \param db   The database to query.
 *  \return A double-pointer to the first item in the list of results
 *          or zero if none.  Use mapper_db_signal_next() to iterate. */
mapper_db_signal_t **mapper_db_get_all_outputs(mapper_db db);

/*! Return the list of inputs for a given device.
 *  \param db          The database to query.
 *  \param device_name Name of the device to match for outputs.  Must
 *                     be exact, including the leading '/'.
 *  \return A double-pointer to the first item in the list of input
 *          signals, or zero if none.  Use mapper_db_signal_next() to
 *          iterate. */
mapper_db_signal_t **mapper_db_get_inputs_by_device_name(
    mapper_db db, const char *device_name);

/*! Return the list of outputs for a given device.
 *  \param db          The database to query.
 *  \param device_name Name of the device to match for outputs.  Must
 *                     be exact, including the leading '/'.
 *  \return A double-pointer to the first item in the list of output
 *          signals, or zero if none.  Use mapper_db_signal_next() to
 *          iterate. */
mapper_db_signal_t **mapper_db_get_outputs_by_device_name(
    mapper_db db, const char *device_name);

/*! Find information for a registered input signal.
 *  \param db          The database to query.
 *  \param device_name Name of the device to find in the database.
 *  \param signal_name Name of the input signal to find in the database.
 *  \return            Information about the signal, or zero if not found. */
mapper_db_signal mapper_db_get_input_by_device_and_signal_names(
    mapper_db db, const char *device_name, const char *signal_name);

/*! Find information for a registered output signal.
 *  \param db          The database to query.
 *  \param device_name Name of the device to find in the database.
 *  \param signal_name Name of the output signal to find in the database.
 *  \return            Information about the signal, or zero if not found. */
mapper_db_signal mapper_db_get_output_by_device_and_signal_names(
    mapper_db db, const char *device_name, char const *signal_name);

/*! Return the list of inputs for a given device.
 *  \param db            The database to query.
 *  \param device_name   Name of the device to match for inputs.
 *  \param input_pattern A substring to search for in the device inputs.
 *  \return A double-pointer to the first item in the list of input
 *          signals, or zero if none.  Use mapper_db_signal_next() to
 *          iterate. */
mapper_db_signal_t **mapper_db_match_inputs_by_device_name(
    mapper_db db, const char *device_name, const char *input_pattern);

/*! Return the list of outputs for a given device.
 *  \param db             The database to query.
 *  \param device_name    Name of the device to match for outputs.
 *  \param output_pattern A substring to search for in the device outputs.
 *  \return A double-pointer to the first item in the list of output
 *          signals, or zero if none.  Use mapper_db_signal_next() to
 *          iterate. */
mapper_db_signal_t **mapper_db_match_outputs_by_device_name(
    mapper_db db, const char *device_name, char const *output_pattern);

/*! Given a signal record pointer returned from a previous
 *  mapper_db_get_*() call, get the next item in the list.
 *  \param  s The previous signal record pointer.
 *  \return A double-pointer to the next signal record in the list, or
 *          zero if no more signals. */
mapper_db_signal_t **mapper_db_signal_next(mapper_db_signal_t **s);

/*! Given a signal record pointer returned from a previous
 *  mapper_db_get_*() call, indicate that we are done iterating.
 *  \param s The previous signal record pointer. */
void mapper_db_signal_done(mapper_db_signal_t **s);

/*! Look up a signal property by index. To iterate all properties,
 *  call this function from index=0, increasing until it returns zero.
 *  \param sig      The signal to look at.
 *  \param index    Numerical index of a signal property.
 *  \param property Address of a string pointer to receive the name of
 *                  indexed property.  May be zero.
 *  \param type     A pointer to a location to receive the type of the
 *                  property value. (Required.)
 *  \param value    A pointer to a location to receive the address of the
 *                  property's value. (Required.)
 *  \param length   A pointer to a location to receive the vector length of
 *                  the property value. (Required.)
 *  \return Zero if found, otherwise non-zero. */
int mapper_db_signal_property_index(mapper_db_signal sig, unsigned int index,
                                    const char **property, char *type,
                                    const void **value, int *length);

/*! Look up a signal property by name.
 *  \param sig      The signal to look at.
 *  \param property The name of the property to retrive.
 *  \param type     A pointer to a location to receive the type of the
 *                  property value. (Required.)
 *  \param value    A pointer to a location to receive the address of the
 *                  property's value. (Required.)
 *  \param length   A pointer to a location to receive the vector length of
 *                  the property value. (Required.)
 *  \return Zero if found, otherwise non-zero. */
int mapper_db_signal_property_lookup(mapper_db_signal sig,
                                     const char *property, char *type,
                                     const void **value, int *length);

/* @} */

/***** Connections *****/

/*! @defgroup connectiondb Connections database

    @{ A monitor may query information about connections between
       signals on the network through this interface.  It is also used
       to specify properties during connection requests. */

/*! A callback function prototype for when a connection record is
 *  added or updated in the database. Such a function is passed in to
 *  mapper_db_add_connection_callback().
 *  \param record  Pointer to the connection record.
 *  \param action  A value of mapper_db_action_t indicating what
 *                 is happening to the database record.
 *  \param user    The user context pointer registered with this
 *                 callback. */
typedef void mapper_db_connection_handler(mapper_db_connection record,
                                          mapper_db_action_t action,
                                          void *user);

/*! Register a callback for when a connection record is added or
 *  updated in the database.
 *  \param db   The database to query.
 *  \param h    Callback function.
 *  \param user A user-defined pointer to be passed to the callback
 *              for context . */
void mapper_db_add_connection_callback(mapper_db db,
                                       mapper_db_connection_handler *h,
                                       void *user);

/*! Remove a connection record callback from the database service.
 *  \param db   The database to query.
 *  \param h    Callback function.
 *  \param user The user context pointer that was originally specified
 *              when adding the callback. */
void mapper_db_remove_connection_callback(mapper_db db,
                                          mapper_db_connection_handler *h,
                                          void *user);

/*! Return a list of all registered connections.
 *  \param db The database to query.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_connection_next() to
 *          iterate. */
mapper_db_connection_t **mapper_db_get_all_connections(mapper_db db);

/*! Return the list of connections that touch the given device name.
 *  \param db          The database to query.
 *  \param device_name Name of the device to find.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_connection_next() to
 *          iterate. */
mapper_db_connection_t **mapper_db_get_connections_by_device_name(
    mapper_db db, const char *device_name);

/*! Return the list of connections for a given source signal name.
 *  \param  db         The database to query.
 *  \param  src_signal Name of the source signal.
 *  \return A double-pointer to the first item in the list of results
 *          or zero if none.  Use mapper_db_connection_next() to
 *          iterate. */
mapper_db_connection_t **mapper_db_get_connections_by_src_signal_name(
    mapper_db db, const char *src_signal);

/*! Return the list of connections for given source device and signal names.
 *  \param db         The database to query.
 *  \param src_device Exact name of the device to find, including the
 *                    leading '/'.
 *  \param src_signal Exact name of the signal to find,
 *                    including the leading '/'.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_connection_next() to
 *          iterate. */
mapper_db_connection_t **mapper_db_get_connections_by_src_device_and_signal_names(
    mapper_db db, const char *src_device, const char *src_signal);

/*! Return the list of connections for a given destination signal name.
 *  \param db          The database to query.
 *  \param dest_signal Name of the destination signal to find.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_connection_next() to
 *          iterate. */
mapper_db_connection_t **mapper_db_get_connections_by_dest_signal_name(
    mapper_db db, const char *dest_signal);

/*! Return the list of connections for given destination device and signal names.
 *  \param db          The database to query.
 *  \param dest_device Exact name of the device to find, including the
 *                     leading '/'.
 *  \param dest_signal Exact name of the signal to find, including the
 *                     leading '/'.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_connection_next() to
 *          iterate. */
mapper_db_connection_t **mapper_db_get_connections_by_dest_device_and_signal_names(
    mapper_db db, const char *dest_device, const char *dest_signal);

/*! Return the list of connections that touch any signals in the lists
 *  of sources and destinations provided.
 *  \param db          The database to query.
 *  \param src_device  Exact name of the device to find, including the
 *                     leading '/'.
 *  \param src_signal  Exact name of the signal to find, including the
 *                     leading '/'.
 *  \param dest_device Exact name of the device to find, including the
 *                     leading '/'.
 *  \param dest_signal Exact name of the signal to find, including the
 *                     leading '/'.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_connection_next() to
 *          iterate. */
mapper_db_connection_t **mapper_db_get_connections_by_device_and_signal_names(
    mapper_db db,
    const char *src_device,  const char *src_signal,
    const char *dest_device, const char *dest_signal);

/*! Return the connection that match the exact source and destination
 *  specified by their full names ("/<device>/<signal>").
 *  \param db        The database to query.
 *  \param src_name  Full name of source signal.
 *  \param dest_name Full name of destination signal.
 *  \return A pointer to a structure containing information on the
 *          found connection, or 0 if not found. */
mapper_db_connection mapper_db_get_connection_by_signal_full_names(
    mapper_db db, const char *src_name, const char *dest_name);

/*! Return connections that have the specified source and destination
 *  devices.
 *  \param db               The database to query.
 *  \param src_device_name  Name of source device.
 *  \param dest_device_name Name of destination device.
 *  \return A double-pointer to the first item in a list of results,
 *          or 0 if not found. */
mapper_db_connection_t **mapper_db_get_connections_by_src_dest_device_names(
    mapper_db db,
    const char *src_device_name, const char *dest_device_name);

/*! Return the list of connections that touch any signals in the lists
 *  of sources and destinations provided.
 *  \param db   The database to query.
 *  \param src  Double-pointer to the first item in a list
 *              returned from a previous database query.
 *  \param dest Double-pointer to the first item in a list
 *              returned from a previous database query.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_connection_next() to
 *          iterate. */
mapper_db_connection_t **mapper_db_get_connections_by_signal_queries(
    mapper_db db,
    mapper_db_signal_t **src, mapper_db_signal_t **dest);

/*! Given a connection record pointer returned from a previous
 *  mapper_db_get_connections*() call, get the next item in the list.
 *  \param s The previous connection record pointer.
 *  \return  A double-pointer to the next connection record in the
 *           list, or zero if no more connections. */
mapper_db_connection_t **mapper_db_connection_next(mapper_db_connection_t **s);

/*! Given a connection record pointer returned from a previous
 *  mapper_db_get_*() call, indicate that we are done iterating.
 *  \param s The previous connection record pointer. */
void mapper_db_connection_done(mapper_db_connection_t **s);

/*! Look up a connection property by index. To iterate all properties,
 *  call this function from index=0, increasing until it returns zero.
 *  \param con      The connection to look at.
 *  \param index    Numerical index of a connection property.
 *  \param property Address of a string pointer to receive the name of
 *                  indexed property.  May be zero.
 *  \param type     A pointer to a location to receive the type of the
 *                  property value. (Required.)
 *  \param value    A pointer to a location to receive the address of the
 *                  property's value. (Required.)
 *  \param length   A pointer to a location to receive the vector length of
 *                  the property value. (Required.)
 *  \return Zero if found, otherwise non-zero. */
int mapper_db_connection_property_index(mapper_db_connection con,
                                        unsigned int index,
                                        const char **property, char *type,
                                        const void **value, int *length);

/*! Look up a connection property by name.
 *  \param con      The connection to look at.
 *  \param property The name of the property to retrive.
 *  \param type     A pointer to a location to receive the type of the
 *                  property value. (Required.)
 *  \param value    A pointer to a location to receive the address of the
 *                  property's value. (Required.)
 *  \param length   A pointer to a location to receive the vector length of
 *                  the property value. (Required.)
 *  \return Zero if found, otherwise non-zero. */
int mapper_db_connection_property_lookup(mapper_db_connection con,
                                         const char *property, char *type,
                                         const void **value, int *length);

/* @} */

/***** Links *****/

/*! @defgroup linkdb Links database

    @{ A monitor may query information about links betweend devices on
       the network through this interface. */

/*! A callback function prototype for when a link record is added or
 *  updated in the database. Such a function is passed in to
 *  mapper_db_add_link_callback().
 *  \param record  Pointer to the link record.
 *  \param action  A value of mapper_db_action_t indicating what
 *                 is happening to the database record.
 *  \param user    The user context pointer registered with this
 *                 callback. */
typedef void mapper_db_link_handler(mapper_db_link record,
                                    mapper_db_action_t action,
                                    void *user);

/*! Register a callback for when a link record is added or updated
 *  in the database.
 *  \param db   The database to query.
 *  \param h    Callback function.
 *  \param user A user-defined pointer to be passed to the callback
 *              for context . */
void mapper_db_add_link_callback(mapper_db db,
                                 mapper_db_link_handler *h,
                                 void *user);

/*! Remove a link record callback from the database service.
 *  \param db   The database to query.
 *  \param h    Callback function.
 *  \param user The user context pointer that was originally specified
 *              when adding the callback. */
void mapper_db_remove_link_callback(mapper_db db,
                                    mapper_db_link_handler *h,
                                    void *user);

/*! Return the whole list of links.
 *  \param db The database to query.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_link_next() to iterate. */
mapper_db_link_t **mapper_db_get_all_links(mapper_db db);

/*! Return the list of links that touch the given device name.
 *  \param db       The database to query.
 *  \param dev_name Name of the device to find.
 *  \return A double-pointer to the first item in the list of results,
 *          or zero if none.  Use mapper_db_link_next() to iterate. */
mapper_db_link_t **mapper_db_get_links_by_device_name(
    mapper_db db, const char *dev_name);

/*! Return the list of links for a given source name.
 *  \param db              The database to query.
 *  \param src_device_name Name of the source device to find.
 *  \return A double-pointer to the first item in the list of source
 *          signals, or zero if none.  Use mapper_db_signal_next() to
 *          iterate. */
mapper_db_link_t **mapper_db_get_links_by_src_device_name(
    mapper_db db, const char *src_device_name);

/*! Return the list of links for a given destination name.
 *  \param db               The database to query.
 *  \param dest_device_name Name of the destination device to find.
 *  \return A double-pointer to the first item in the list of destination
 *          signals, or zero if none.  Use mapper_db_signal_next() to
 *          iterate. */
mapper_db_link_t **mapper_db_get_links_by_dest_device_name(
    mapper_db db, const char *dest_device_name);

/*! Return the link structure associated with the exact devices specified.
 *  \param db               The database to query.
 *  \param src_device_name  Name of the source device to find.
 *  \param dest_device_name Name of the destination device to find.
 *  \return A structure containing information on the link, or 0 if
 *          not found. */
mapper_db_link mapper_db_get_link_by_src_dest_names(mapper_db db,
    const char *src_device_name, const char *dest_device_name);

/*! Return the list of links that touch devices in both src and dest lists.
 *  \param db The database to query.
 *  \param src_device_list  Double-pointer to the first item in a list
 *                          returned from a previous database query.
 *  \param dest_device_list Double-pointer to the first item in a list
 *                          returned from a previous database query.
 *  \return A double-pointer to the first item in the list of links,
 *          or zero if none.  Use mapper_db_link_next() to iterate. */
mapper_db_link_t **mapper_db_get_links_by_src_dest_devices(
    mapper_db db,
    mapper_db_device_t **src_device_list,
    mapper_db_device_t **dest_device_list);

/*! Given a link record double-pointer returned from a previous
 *  mapper_db_get_links*() call, get the next item in the list.
 *  \param s The previous link record double-pointer.
 *  \return A double-pointer to the next link record in the list, or
 *          zero if no more links. */
mapper_db_link_t **mapper_db_link_next(mapper_db_link_t **s);

/*! Given a link record double-pointer returned from a previous
 *  mapper_db_get_*() call, indicate that we are done iterating.
 *  \param s The previous link record double-pointer. */
void mapper_db_link_done(mapper_db_link_t **s);

/*! Look up a link property by index. To iterate all properties,
 *  call this function from index=0, increasing until it returns zero.
 *  \param link     The link to look at.
 *  \param index    Numerical index of a link property.
 *  \param property Address of a string pointer to receive the name of
 *                  indexed property.  May be zero.
 *  \param type     A pointer to a location to receive the type of the
 *                  property value. (Required.)
 *  \param value    A pointer to a location to receive the address of the
 *                  property's value. (Required.)
 *  \param length   A pointer to a location to receive the vector length of
 *                  the property value. (Required.)
 *  \return Zero if found, otherwise non-zero. */
int mapper_db_link_property_index(mapper_db_link link, unsigned int index,
                                  const char **property, char *type,
                                  const void **value, int *length);

/*! Look up a link property by name.
 *  \param link     The link to look at.
 *  \param property The name of the property to retrive.
 *  \param type     A pointer to a location to receive the type of the
 *                  property value. (Required.)
 *  \param value    A pointer to a location to receive the address of the
 *                  property's value. (Required.)
 *  \param length   A pointer to a location to receive the vector length of
 *                  the property value. (Required.)
 *  \return Zero if found, otherwise non-zero. */
int mapper_db_link_property_lookup(mapper_db_link link,
                                   const char *property, char *type,
                                   const void **value, int *length);

/* @} */

/***** Monitors *****/

/*! @defgroup monitor Monitors

    @{ Monitors are the primary interface through which a program may
       observe the network and store information about devices and
       signals that are present.  Each monitor has a database of
       devices, signals, connections, and links, which can be queried.
       A monitor can also make link and connection requests.  In
       general, the monitor interface is useful for building GUI
       applications to control the network. */

/*! Bit flags for coordinating monitor metadata subscriptions. Subsets of
 *  device information must also include SUB_DEVICE. */
#define SUB_DEVICE                  0x01
#define SUB_DEVICE_INPUTS           0x03
#define SUB_DEVICE_OUTPUTS          0x05
#define SUB_DEVICE_SIGNALS          0x07 // SUB_DEVICE_INPUTS & SUB_DEVICE_OUTPUTS
#define SUB_DEVICE_LINKS_IN         0x09
#define SUB_DEVICE_LINKS_OUT        0x11
#define SUB_DEVICE_LINKS            0x19 // SUB_DEVICE_LINKS_IN & SUB_DEVICE_LINKS_OUT
#define SUB_DEVICE_CONNECTIONS_IN   0x21
#define SUB_DEVICE_CONNECTIONS_OUT  0x41
#define SUB_DEVICE_CONNECTIONS      0x61 // SUB_DEVICE_CONNECTIONS_IN & SUB_DEVICE_CONNECTION_OUT
#define SUB_DEVICE_ALL              0xFF

/*! Create a network monitor.
 *  \param admin               A previously allocated admin to use.  If 0, an
 *                             admin will be allocated for use with this monitor.
 *  \param autosubscribe_flags Sets whether the monitor should automatically
 *                             subscribe to information about signals, links,
 *                             and connections when it encounters a
 *                             previously-unseen device.
 *  \return The new monitor. */
mapper_monitor mapper_monitor_new(mapper_admin admin, int autosubscribe_flags);

/*! Free a network monitor. */
void mapper_monitor_free(mapper_monitor mon);

/*! Poll a network monitor.
 *  \param mon      The monitor to poll.
 *  \param block_ms The number of milliseconds to block, or 0 for
 *                  non-blocking behaviour.
 *  \return The number of handled messages. */
int mapper_monitor_poll(mapper_monitor mon, int block_ms);

/*! Get the database associated with a monitor. This can be used as
 *  long as the monitor remains alive. */
mapper_db mapper_monitor_get_db(mapper_monitor mon);

/*! Set the timeout in seconds after which a monitor will declare a device
 *  "unresponsive". Defaults to ADMIN_TIMEOUT_SEC.
 *  \param mon      The monitor to use.
 *  \param timeout  The timeout in seconds. */
void mapper_monitor_set_timeout(mapper_monitor mon, int timeout);

/*! Get the timeout in seconds after which a monitor will declare a device
 *  "unresponsive". Defaults to ADMIN_TIMEOUT_SEC.
 *  \param mon      The monitor to use.
 *  \return The current timeout in seconds. */
int mapper_monitor_get_timeout(mapper_monitor mon);

/*! Remove unresponsive devices from the database.
 *  \param mon         The monitor to use.
 *  \param timeout_sec The number of seconds a device must have been
 *                     unresponsive before removal.
 *  \param quiet       1 to disable callbacks during db flush, 0 otherwise. */
void mapper_monitor_flush_db(mapper_monitor mon, int timeout_sec, int quiet);

/*! Request that all devices report in. */
void mapper_monitor_request_devices(mapper_monitor mon);

/*! Subscribe to information about a specific device.
 *  \param mon             The monitor to use.
 *  \param device_name     The name of the device of interest.
 *  \param subscribe_flags Bitflags setting the type of information of interest.
 *                         Can be a combination of SUB_DEVICE, SUB_DEVICE_INPUTS,
 *                         SUB_DEVICE_OUTPUTS, SUB_DEVICE_SIGNALS,
 *                         SUB_DEVICE_LINKS_IN, SUB_DEVICE_LINKS_OUT,
 *                         SUB_DEVICE_LINKS, SUB_DEVICE_CONNECTIONS_IN,
 *                         SUB_DEVICE_CONNECTIONS_OUT, SUB_DEVICE_CONNECTIONS,
 *                         or simply SUB_DEVICE_ALL for all information.
 *  \param timeout         The length in seconds for this subscription. If set
 *                         to -1, libmapper will automatically renew the
 *                         subscription until the monitor is freed or this
 *                         function is called again. */
void mapper_monitor_subscribe(mapper_monitor mon, const char *device_name,
                              int subscribe_flags, int timeout);

/*! Unsubscribe from information about a specific device.
 *  \param mon             The monitor to use.
 *  \param device_name     The name of the device of interest. */
void mapper_monitor_unsubscribe(mapper_monitor mon, const char *device_name);

/*! Sets whether the monitor should automatically subscribe to
 *  information on signals, links, and connections when it encounters
 *  a previously-unseen device.*/
void mapper_monitor_autosubscribe(mapper_monitor mon, int autosubscribe_flags);

/*! Interface to add a link between two devices.
 *  \param mon            The monitor to use for sending the message.
 *  \param source_device  Source device name.
 *  \param dest_device    Destination device name.
 *  \param properties     An optional data structure specifying the
 *                        requested properties of this link.
 *  \param property_flags Bit flags indicating which properties in the
 *                        provided mapper_db_link_t should be
 *                        applied to the new link. See the flags
 *                        prefixed by LINK_ in mapper_db.h. */
void mapper_monitor_link(mapper_monitor mon,
                         const char* source_device,
                         const char* dest_device,
                         mapper_db_link_t *properties,
                         unsigned int property_flags);

/*! Interface to remove a link between two devices.
 *  \param mon           The monitor to use for sending the message.
 *  \param source_device Source device name.
 *  \param dest_device   Destination device name. */
void mapper_monitor_unlink(mapper_monitor mon,
                           const char* source_device,
                           const char* dest_device);

/*! Interface to modify a connection between two signals.
 *  \param mon            The monitor to use for sending the message.
 *  \param source_signal  Source signal name.
 *  \param dest_signal    Destination signal name.
 *  \param properties     An optional data structure specifying the
 *                        requested properties of this connection.
 *  \param property_flags Bit flags indicating which properties in the
 *                        provided mapper_db_connection_t should be
 *                        applied to the new connection. See the flags
 *                        prefixed by CONNECTION_ in mapper_db.h. */
void mapper_monitor_connection_modify(mapper_monitor mon,
                                      const char *source_signal,
                                      const char *dest_signal,
                                      mapper_db_connection_t *properties,
                                      unsigned int property_flags);

/*! Interface to add a connection between two signals.
 *  \param mon The monitor to use for sending the message.
 *  \param source_signal  Source signal name.
 *  \param dest_signal    Destination signal name.
 *  \param properties     An optional data structure specifying the
 *                        requested properties of this connection.
 *  \param property_flags Bit flags indicating which properties in the
 *                        provided mapper_db_connection_t should be
 *                        applied to the new connection. See the flags
 *                        prefixed by CONNECTION_ in mapper_db.h. */
void mapper_monitor_connect(mapper_monitor mon,
                            const char* source_signal,
                            const char* dest_signal,
                            mapper_db_connection_t *properties,
                            unsigned int property_flags);

/*! Interface to remove a connection between two signals.
 *  \param mon           The monitor to use for sending the message.
 *  \param source_signal Source signal name.
 *  \param dest_signal   Destination signal name. */
void mapper_monitor_disconnect(mapper_monitor mon,
                               const char* source_signal,
                               const char* dest_signal);

/* @} */

/***** Time *****/

/*! @defgroup time Time
 
 @{ libmapper primarily uses NTP timetags for communication and
    synchronization. */

/*! Initialize a timetag to the current mapping network time.
 *  \param dev  The device whose time we are asking for.
 *  \param tt   A previously allocated timetag to initialize. */
void mdev_now(mapper_device dev,
              mapper_timetag_t *tt);

/*! Initialize a timetag to the current mapping network time.
 *  \param mon  The monitor whose time we are asking for.
 *  \param tt   A previously allocated timetag to initialize. */
void mapper_monitor_now(mapper_monitor mon,
                        mapper_timetag_t *tt);

/*! Return the difference in seconds between two mapper_timetags.
 *  \param a    The minuend.
 *  \param b    The subtrahend.
 *  \return     The difference a-b in seconds. */
double mapper_timetag_difference(mapper_timetag_t a, mapper_timetag_t b);

/*! Add seconds to a given timetag.
 *  \param tt       A previously allocated timetag to augment.
 *  \param addend   An amount in seconds to add. */
void mapper_timetag_add_seconds(mapper_timetag_t *tt, double addend);

/*! Return value of mapper_timetag as a double-precision floating point value.
 *  \param tt   The timetag to read.
 *  \return     The timetag value in seconds. */
double mapper_timetag_get_double(mapper_timetag_t tt);

/*! Set value of a mapper_timetag from an integer value.
 *  \param tt       The timetag to set.
 *  \param value    Time value in seconds. */
void mapper_timetag_set_int(mapper_timetag_t *tt, int value);

/*! Set value of a mapper_timetag from a floating point value.
 *  \param tt       The timetag to set.
 *  \param value    Time value in seconds. */
void mapper_timetag_set_float(mapper_timetag_t *tt, float value);

/*! Set value of a mapper_timetag from a double-precision floating point value.
 *  \param tt       The timetag to set.
 *  \param value    Time value in seconds. */
void mapper_timetag_set_double(mapper_timetag_t *tt, double value);

/*! Copy value of a mapper_timetag. */
void mapper_timetag_cpy(mapper_timetag_t *ttl, mapper_timetag_t ttr);

/* @} */

#ifdef __cplusplus
}
#endif

#endif // __MAPPER_H__