shell/sc_nimble_netif: extend to support PHY modes

--- sys/shell/commands/sc_nimble_netif.c
+++ sys/shell/commands/sc_nimble_netif.c
@@ -21,6 +21,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdbool.h>

 #include "fmt.h"
 #include "ztimer.h"
@@ -30,17 +31,37 @@
 #include "net/bluetil/ad.h"
 #include "net/bluetil/addr.h"

-#if !IS_USED(MODULE_NIMBLE_AUTOCONN) && !IS_USED(MODULE_NIMBLE_STATCONN)
+#define FULL_CONTROL            !IS_USED(MODULE_NIMBLE_AUTOCONN) && \
+                                !IS_USED(MODULE_NIMBLE_STATCONN) && \
+                                !IS_USED(MODULE_NIMBLE_RPBLE)
+
+#if FULL_CONTROL
 #include "nimble_scanlist.h"
 #include "nimble_scanner.h"
 #endif

-#define DEFAULT_NODE_NAME           "bleRIOT"
-#define DEFAULT_SCAN_DURATION       (500U)      /* 500ms */
-#define DEFAULT_CONN_TIMEOUT        (500U)      /* 500ms */
-
-#if !IS_USED(MODULE_NIMBLE_AUTOCONN) && !IS_USED(MODULE_NIMBLE_STATCONN)
+#define DEFAULT_SCAN_DURATION_MS    500U
+#define DEFAULT_CONN_TIMEOUT_MS     500U
+#define DEFAULT_SCAN_ITVL_MS        100U
+#define DEFAULT_CONN_ITVL_MS        75U
+#define DEFAULT_TX_POWER            0           /* 0dBm */
+#define DEFAULT_ADV_ITVL_MS         75U
+
+static const char *_phystr[] = { "N/A", "1M", "2M", "CODED" };
+
+#if FULL_CONTROL
 static const char *_name_to_connect = NULL;
+static nimble_netif_connect_cfg_t _connect_params = {
+    .scan_itvl_ms = DEFAULT_SCAN_ITVL_MS,
+    .scan_window_ms = DEFAULT_SCAN_ITVL_MS,
+    .conn_itvl_min_ms = DEFAULT_CONN_ITVL_MS,
+    .conn_itvl_max_ms = DEFAULT_CONN_ITVL_MS,
+    .conn_supervision_timeout_ms = DEFAULT_CONN_ITVL_MS * 20,
+    .conn_slave_latency = 0,
+    .timeout_ms = 0,       /* will be filled later */
+    .phy_mode = 0,      /* will be filled later */
+    .own_addr_type = 0  /* will be filled later */,
+};

 static void _scan_for_name(uint8_t type, const ble_addr_t *addr,
                            const nimble_scanner_info_t *info,
@@ -56,7 +77,7 @@
                                   _name_to_connect, strlen(_name_to_connect));
     if (res) {
         nimble_scanner_stop();
-        nimble_netif_connect(addr, NULL, DEFAULT_CONN_TIMEOUT);
+        nimble_netif_connect(addr, &_connect_params);
     }
 }

@@ -90,10 +111,32 @@
         case NIMBLE_NETIF_ABORT_SLAVE:
             _print_evt("CONNECTION ABORT", handle, addr);
             break;
+        case NIMBLE_NETIF_ACCEPT_STOP:
+            _print_evt("ACCEPT STOP", handle, addr);
         case NIMBLE_NETIF_CONN_UPDATED:
         default:
             /* do nothing */
             break;
+    }
+}
+
+static uint8_t _parsephy(const char *phy_str)
+{
+    if (memcmp(phy_str, "1M", 2) == 0) {
+        return NIMBLE_PHY_1M;
+    }
+#if IS_ACTIVE(MODULE_NIMBLE_PHY_2MBIT)
+    else if (memcmp(phy_str, "2M", 2) == 0) {
+        return NIMBLE_PHY_2M;
+    }
+#endif
+#if IS_ACTIVE(MODULE_NIMBLE_PHY_CODED)
+    else if (memcmp(phy_str, "CODED", 5) == 0) {
+        return NIMBLE_PHY_CODED;
+    }
+#endif
+    else {
+        return NIMBLE_PHY_INVALID;
     }
 }
 #endif
@@ -117,8 +160,20 @@
     printf(" ");
     bluetil_addr_ipv6_l2ll_print(conn->addr);
 #endif
-    printf(" (%c,%ums,%ums,%i)", role, itvl, sto, (int)desc.conn_latency);
-    puts("");
+
+#if IS_USED(MODULE_NIMBLE_NETIF_EXT)
+    uint8_t phy_rx, phy_tx;
+    (void)phy_tx;
+    res = ble_gap_read_le_phy(conn->gaphandle, &phy_tx, &phy_rx);
+    if (res != 0) {
+        phy_rx = 1;
+    }
+#else
+    /* when not using extended advertisements we always use the 1M phy mode */
+    uint8_t phy_rx = 1;
+#endif
+    printf(" (%c,%ums,%ums,%i,%s)\n",
+            role, itvl, sto, (int)desc.conn_latency, _phystr[phy_rx]);

     return 0;
 }
@@ -159,7 +214,7 @@
     if (active > 0) {
         nimble_netif_conn_foreach(NIMBLE_NETIF_L2CAP_CONNECTED,
                                   _conn_dump, NULL);
-        puts("     (role, conn itvl, superv. timeout, slave latency)");
+        puts("     (role, conn itvl, superv. timeout, slave latency, PHY)");
     }
 }

@@ -179,6 +234,15 @@
 #endif
     puts("");

+    printf("Supported PHY modes: 1M");
+#if IS_USED(MODULE_NIMBLE_PHY_2MBIT)
+    printf(" 2M");
+#endif
+#if IS_USED(MODULE_NIMBLE_PHY_CODED)
+    printf(" CODED");
+#endif
+    puts("");
+
     printf(" Free slots: %u/%u\n", free, NIMBLE_NETIF_MAX_CONN);
     printf("Advertising: ");
     if (nimble_netif_conn_get_adv() != NIMBLE_NETIF_CONN_INVALID) {
@@ -196,99 +260,107 @@
     puts("");
 }

-#if !IS_USED(MODULE_NIMBLE_AUTOCONN) && !IS_USED(MODULE_NIMBLE_STATCONN)
-static void _cmd_adv(const char *name)
+#if FULL_CONTROL
+static int _cmd_adv(int argc, char **argv, bool legacy)
 {
     int res;
     (void)res;
-    uint8_t buf[BLE_HS_ADV_MAX_SZ];
-    bluetil_ad_t ad;
-    const struct ble_gap_adv_params _adv_params = {
-        .conn_mode = BLE_GAP_CONN_MODE_UND,
-        .disc_mode = BLE_GAP_DISC_MODE_LTD,
-        .itvl_min = BLE_GAP_ADV_FAST_INTERVAL2_MIN,
-        .itvl_max = BLE_GAP_ADV_FAST_INTERVAL2_MAX,
-    };
+    const char *name = NULL;
+    uint8_t addrn[BLE_ADDR_LEN];
+    ble_addr_t addr = { .type = nimble_riot_own_addr_type };
+
+    /* stop sub-command: stop advertising */
+    if (memcmp(argv[2], "stop", 4) == 0) {
+        res = nimble_netif_accept_stop();
+        if (res == 0) {
+            puts("advertising stopped");
+        }
+        else if (res == -EALREADY) {
+            puts("no advertising in progress");
+        }
+        return 0;
+    }

     /* make sure no advertising is in progress */
     if (nimble_netif_conn_is_adv()) {
         puts("err: advertising already in progress");
-        return;
-    }
-
-    /* build advertising data */
-    res = bluetil_ad_init_with_flags(&ad, buf, BLE_HS_ADV_MAX_SZ,
-                                     BLUETIL_AD_FLAGS_DEFAULT);
-    assert(res == BLUETIL_AD_OK);
-    uint16_t ipss = BLE_GATT_SVC_IPSS;
-    res = bluetil_ad_add(&ad, BLE_GAP_AD_UUID16_INCOMP, &ipss, sizeof(ipss));
-    assert(res == BLUETIL_AD_OK);
-    if (name == NULL) {
-        name = DEFAULT_NODE_NAME;
-    }
-    res = bluetil_ad_add(&ad, BLE_GAP_AD_NAME, name, strlen(name));
-    if (res != BLUETIL_AD_OK) {
-        puts("err: the given name is too long");
-        return;
-    }
-
-    /* start listening for incoming connections */
-    res = nimble_netif_accept(ad.buf, ad.pos, &_adv_params);
+        return 1;
+    }
+
+    /* try if first parameter is a BLE address, if so, use directed
+     * advertisement */
+    if (bluetil_addr_from_str(addrn, argv[2]) != NULL) {
+        /* NimBLE expects address in little endian, so swap */
+        bluetil_addr_swapped_cp(addrn, addr.val);
+        puts("Found BLE address: sending directed advertisements");
+    }
+    else {
+        name = argv[2];
+    }
+
+    uint32_t timeout = 0;
+    if (argc >= 4) {
+        timeout = (uint32_t)atoi(argv[3]);
+    }
+
+    uint8_t phy_sec = BLE_GAP_LE_PHY_1M;
+    if (argc >= 5) {
+        phy_sec = _parsephy(argv[4]);
+        if (phy_sec == 0) {
+            puts("err: PHY mode not supported\n");
+            return 1;
+        }
+    }
+    uint8_t phy_pri = (phy_sec == BLE_HCI_LE_PHY_2M) ? BLE_HCI_LE_PHY_1M
+                                                     : phy_sec;
+
+    nimble_netif_accept_cfg_t p = {
+        .flags = (legacy) ? NIMBLE_NETIF_FLAG_LEGACY : 0,
+        .adv_itvl_ms = DEFAULT_ADV_ITVL_MS,
+        .primary_phy = phy_pri,
+        .secondary_phy = phy_sec,
+        .tx_power = DEFAULT_TX_POWER,
+        .channel_map = 0,
+        .timeout_ms = timeout,
+        .own_addr_type = nimble_riot_own_addr_type,
+    };
+
+    if (name != NULL) {
+        uint8_t buf[BLE_HS_ADV_MAX_SZ];
+        bluetil_ad_t ad;
+        /* build advertising data */
+        res = bluetil_ad_init_with_flags(&ad, buf, BLE_HS_ADV_MAX_SZ,
+                                         BLUETIL_AD_FLAGS_DEFAULT);
+        assert(res == BLUETIL_AD_OK);
+        uint16_t ipss = BLE_GATT_SVC_IPSS;
+        res = bluetil_ad_add(&ad, BLE_GAP_AD_UUID16_INCOMP, &ipss, sizeof(ipss));
+        assert(res == BLUETIL_AD_OK);
+        res = bluetil_ad_add(&ad, BLE_GAP_AD_NAME, name, strlen(name));
+        if (res != BLUETIL_AD_OK) {
+            puts("err: the given name is too long");
+            return 1;
+        }
+
+        res = nimble_netif_accept(ad.buf, ad.pos, &p);
+    }
+    else {
+        res = nimble_netif_accept_direct(&addr, &p);
+    }
+
     if (res != 0) {
         printf("err: unable to start advertising (%i)\n", res);
     }
     else {
-        printf("success: advertising this node as '%s'\n", name);
-    }
-}
-
-static void _cmd_adv_direct(const char *addr_str)
-{
-    int res;
-    (void)res;
-    uint8_t addrn[BLE_ADDR_LEN];
-    ble_addr_t addr;
-    const struct ble_gap_adv_params _adv_params = {
-        .conn_mode = BLE_GAP_CONN_MODE_DIR,
-        .disc_mode = BLE_GAP_DISC_MODE_GEN,
-        .itvl_min = BLE_GAP_ADV_FAST_INTERVAL2_MIN,
-        .itvl_max = BLE_GAP_ADV_FAST_INTERVAL2_MAX,
-    };
-
-    /* make sure no advertising is in progress */
-    if (nimble_netif_conn_is_adv()) {
-        puts("err: advertising already in progress");
-        return;
-    }
-
-    /* parse and convert address -> RIOT uses big endian notation, NimBLE
-     * expects little endian... */
-    if (bluetil_addr_from_str(addrn, addr_str) == NULL) {
-        puts("err: unable to parse BLE address");
-        return;
-    }
-    addr.type = nimble_riot_own_addr_type;
-    bluetil_addr_swapped_cp(addrn, addr.val);
-
-    /* start advertising directed advertising with the given BLE address */
-    res = nimble_netif_accept_direct(&addr, BLE_HS_FOREVER, &_adv_params);
-    if (res != 0) {
-        printf("err: unable to start directed advertising (%i)\n", res);
-    }
-    else {
-        puts("success: started to send directed advertisements");
-    }
-}
-
-static void _cmd_adv_stop(void)
-{
-    int res = nimble_netif_accept_stop();
-    if (res == 0) {
-        puts("canceled advertising");
-    }
-    else {
-        puts("no advertising in progress");
-    }
+        if (name != NULL) {
+            printf("success: advertising this node as '%s'\n", name);
+        }
+        else {
+            printf("success: sending direct advertisements to ");
+            bluetil_addr_print(addrn);
+            puts("");
+        }
+    }
+    return 0;
 }

 static void _do_scan(nimble_scanner_cb cb, unsigned duration)
@@ -301,7 +373,19 @@
         printf("err: scanner already active\n");
         return;
     }
-    nimble_scanner_init(NULL, cb);
+
+    nimble_scanner_cfg_t p = {
+        .itvl_ms = DEFAULT_SCAN_ITVL_MS,
+        .win_ms = DEFAULT_SCAN_ITVL_MS,
+#if IS_USED(MODULE_NIMBLE_PHY_CODED)
+        .flags = (NIMBLE_SCANNER_PASSIVE | NIMBLE_SCANNER_PHY_1M |
+                  NIMBLE_SCANNER_PHY_CODED),
+#else
+        .flags = (NIMBLE_SCANNER_PASSIVE | NIMBLE_SCANNER_PHY_1M),
+#endif
+    };
+
+    nimble_scanner_init(&p, cb);
     nimble_scanlist_clear();
     nimble_scanner_start();
     ztimer_sleep(ZTIMER_MSEC, duration);
@@ -316,58 +400,73 @@
     nimble_scanlist_print();
 }

-static void _cmd_connect_addr(ble_addr_t *addr)
-{
-    /* simply use NimBLEs default connection parameters */
-    int res = nimble_netif_connect(addr, NULL, DEFAULT_CONN_TIMEOUT);
-    if (res < 0) {
-        printf("err: unable to trigger connection sequence (%i)\n", res);
+static void _cmd_connect(int argc, char **argv)
+{
+    ble_addr_t addr;
+    int proceed = 0;
+
+    /* populate connection parameters */
+    _connect_params.timeout_ms = DEFAULT_CONN_TIMEOUT_MS;
+    if (argc >= 4) {
+        _connect_params.timeout_ms = (uint32_t)atoi(argv[3]);
+    }
+    _connect_params.phy_mode = NIMBLE_PHY_1M;
+    if (argc >= 5) {
+        _connect_params.phy_mode = _parsephy(argv[4]);
+        if (_connect_params.phy_mode == 0) {
+            puts("err: PHY mode not supported\n");
+            return;
+        }
+    }
+    _connect_params.own_addr_type = nimble_riot_own_addr_type;
+
+    /* try to parse address directly */
+    uint8_t addrn[BLE_ADDR_LEN];
+    if (bluetil_addr_from_str(addrn, argv[2]) != NULL) {
+        addr.type = nimble_riot_own_addr_type;
+        /* NimBLE expects address in little endian, so swap */
+        bluetil_addr_swapped_cp(addrn, addr.val);
+        proceed = 1;
+    }
+    /* try if param is a number, if so use it as scanlist entry number */
+    else if (fmt_is_number(argv[2])) {
+        unsigned pos = atoi(argv[2]);
+        nimble_scanlist_entry_t *sle = nimble_scanlist_get_by_pos(pos);
+        if (sle == NULL) {
+            puts("err: unable to find given entry in scanlist");
+            return;
+        }
+        _connect_params.phy_mode = sle->phy_sec;
+        memcpy(&addr, &sle->addr, sizeof(addr));
+        proceed = 1;
+    }
+    /* else interpret value as name and search for that peer */
+    else {
+        unsigned duration = DEFAULT_SCAN_DURATION_MS;
+        if (argc > 3) {
+            duration = atoi(argv[3]);
+        }
+        _name_to_connect = argv[2];
+        printf("trying to find and connect to a node with name '%s'\n", argv[2]);
+        _do_scan(_scan_for_name, duration);
+        if (_name_to_connect != NULL) {
+            printf("fail: unable to connect to '%s'\n", _name_to_connect);
+            _name_to_connect = NULL;
+        }
         return;
     }

-    printf("initiated connection procedure with ");
-    uint8_t addrn[BLE_ADDR_LEN];
-    bluetil_addr_swapped_cp(addr->val, addrn);
-    bluetil_addr_print(addrn);
-    puts("");
-
-}
-
-static void _cmd_connect_addr_raw(const uint8_t *addr_in)
-{
-    /* RANDOM is the most common type, has no noticeable effect when connecting
-       anyhow... */
-    ble_addr_t addr = { .type = BLE_ADDR_RANDOM };
-    /* NimBLE expects address in little endian, so swap */
-    bluetil_addr_swapped_cp(addr_in, addr.val);
-    _cmd_connect_addr(&addr);
-}
-
-static void _cmd_connect_name(const char *name, unsigned duration)
-{
-    if (_name_to_connect != NULL) {
-        printf("err: already trying to connect to '%s'\n", _name_to_connect);
-        return;
-    }
-    _name_to_connect = name;
-    printf("trying to find and connect to a node with name '%s'\n", name);
-    _do_scan(_scan_for_name, duration);
-    if (_name_to_connect != NULL) {
-        printf("fail: unable to connect to '%s'\n", _name_to_connect);
-        _name_to_connect = NULL;
-    }
-}
-
-static void _cmd_connect_scanlist(unsigned pos)
-{
-    nimble_scanlist_entry_t *sle = nimble_scanlist_get_by_pos(pos);
-    if (sle == NULL) {
-        puts("err: unable to find given entry in scanlist");
-        return;
-    }
-    _cmd_connect_addr(&sle->addr);
-}
-#endif /* MODULE_NIMBLE_AUTOCONN */
+    if (proceed == 1) {
+        int res = nimble_netif_connect(&addr, &_connect_params);
+        if (res == 0) {
+            puts("Successfully connected 123");
+        }
+        else {
+            puts("err: unable to connect");
+        }
+    }
+}
+#endif

 static void _cmd_close(int handle)
 {
@@ -406,7 +505,7 @@

 void sc_nimble_netif_init(void)
 {
-#if !IS_USED(MODULE_NIMBLE_AUTOCONN) && !IS_USED(MODULE_NIMBLE_STATCONN)
+#if FULL_CONTROL
     /* setup the scanning environment */
     nimble_scanlist_init();

@@ -418,8 +517,9 @@
 int _nimble_netif_handler(int argc, char **argv)
 {
     if ((argc == 1) || _ishelp(argv[1])) {
-#if !IS_USED(MODULE_NIMBLE_AUTOCONN) && !IS_USED(MODULE_NIMBLE_STATCONN)
-        printf("usage: %s [help|info|adv|scan|connect|close|update|chanmap]\n", argv[0]);
+#if FULL_CONTROL
+        printf("usage: %s [help|info|adv|adv_ext|adv_dir|"
+               "scan|connect|close|update|chanmap]\n", argv[0]);
 #else
         printf("usage: %s [help|info|close|update|chanmap]\n", argv[0]);
 #endif
@@ -429,34 +529,26 @@
         _cmd_info();
     }

-#if !IS_USED(MODULE_NIMBLE_AUTOCONN) && !IS_USED(MODULE_NIMBLE_STATCONN)
+#if FULL_CONTROL
+    else if (memcmp(argv[1], "adv_ext", 7) == 0) {
+        if (argc <= 2 || _ishelp(argv[2])) {
+            printf("usage: %s adv_ext <help|stop|addr|name> [timeout] [phy mode]\n"
+                   "        timeout in ms, 0 for no timeout\n"
+                   "        phy mode: [1M|2M|CODED]\n", argv[0]);
+            return 0;
+        }
+        return _cmd_adv(argc, argv, false);
+    }
     else if (memcmp(argv[1], "adv", 3) == 0) {
-        char *name = NULL;
-        if (argc > 2) {
-            if (_ishelp(argv[2])) {
-                printf("usage: %s adv [help|stop|direct <addr>|<name>]\n",
-                       argv[0]);
-                return 0;
-            }
-            if (memcmp(argv[2], "stop", 4) == 0) {
-                _cmd_adv_stop();
-                return 0;
-            }
-            if (memcmp(argv[2], "direct", 6) == 0) {
-                puts("DBG: direct adv");
-                if (argc < 4) {
-                    printf("error, no BLE address given\n");
-                    return 0;
-                }
-                _cmd_adv_direct(argv[3]);
-                return 0;
-            }
-            name = argv[2];
-        }
-        _cmd_adv(name);
+        if (argc <= 2 || _ishelp(argv[2])) {
+            printf("usage: %s adv <help|stop|addr|name> [timeout]\n"
+                   "        timeout in ms, 0 for no timeout\n", argv[0]);
+            return 0;
+        }
+        return _cmd_adv(argc, argv, true);
     }
     else if (memcmp(argv[1], "scan", 4) == 0) {
-        uint32_t duration = DEFAULT_SCAN_DURATION;
+        uint32_t duration = DEFAULT_SCAN_DURATION_MS;
         if (argc > 2) {
             if (_ishelp(argv[2])) {
                 printf("usage: %s scan [help|list|[duration in ms]]\n", argv[0]);
@@ -472,32 +564,16 @@
     }
     else if (memcmp(argv[1], "connect", 7) == 0) {
         if ((argc < 3) || _ishelp(argv[2])) {
-            printf("usage: %s connect [help|list|<scanlist entry #>|<BLE addr>|<name>]\n",
-                   argv[0]);
+            printf("usage: %s %s [help|list|<scanlist #>|<BLE addr>|<name>] "
+                   "[timeout ms] [phy mode]\n"
+                   "        phy mode: [1M|2M|CODED]\n", argv[0], argv[1]);
             return 0;
         }
         if (memcmp(argv[2], "list", 4) == 0) {
             _conn_list();
             return 0;
         }
-        /* try if param is an BLE address */
-        uint8_t addr[BLE_ADDR_LEN];
-        if (bluetil_addr_from_str(addr, argv[2]) != NULL) {
-            _cmd_connect_addr_raw(addr);
-            return 0;
-        }
-        /* try if param is a name (contains non-number chars) */
-        if (!fmt_is_number(argv[2])) {
-            unsigned duration = DEFAULT_SCAN_DURATION;
-            if (argc > 3) {
-                duration = atoi(argv[3]);
-            }
-            _cmd_connect_name(argv[2], duration);
-            return 0;
-        }
-
-        unsigned pos = atoi(argv[2]);
-        _cmd_connect_scanlist(pos);
+        _cmd_connect(argc, argv);
     }
 #endif
     else if (memcmp(argv[1], "close", 5) == 0) {


Explicitly adding include of fastled_progmem here.

--- colorutils.h
+++ colorutils.h
@@ -3,6 +3,7 @@

 #include "pixeltypes.h"
+#include "fastled_progmem.h"

 FASTLED_NAMESPACE_BEGIN
 ///@defgroup Colorutils Color utility functions


now when you try to set an existing key binding, it tells you the name of the action associated with the binding

SVN revision: 24234

--- src/bin/e_int_config_keybindings.c
+++ src/bin/e_int_config_keybindings.c
@@ -1362,6 +1362,8 @@
 	  {
 	     if (cfdata && cfdata->current_act && cfdata->current_act_selector >= 0)
 	       {
+                  ACTION_GROUP *actg;
+                  ACTION2 *act;
 		  Evas_List   *l, *l2, *l3;
 		  int found;
 		  int mod = E_BINDING_MODIFIER_NONE;
@@ -1378,10 +1380,10 @@
 		  found = 0;
 		  for (l = action_group_list; l && !found; l = l->next)
 		    {
-		       ACTION_GROUP *actg = l->data;
+                       actg = l->data;
 		       for (l2 = actg->actions; l2 && !found; l2 = l2->next)
 			 {
-			    ACTION2 *act = l2->data;
+                            act = l2->data;
 			    for (l3 = act->key_bindings; l3 && !found; l3 = l3->next)
 			      {
 				 eb = l3->data;
@@ -1402,10 +1404,18 @@
 		       _e_keybinding_update_binding_list(cfdata);
 		    }
 		  else
-		    e_util_dialog_show(_("Binding Key Error"),
-				       _("The binding key sequence, that you choose,"
-					 " is already used.
Please choose another binding key"
-					 " sequence."));
+                    {
+                       char buf[4096];
+
+                       snprintf(buf, sizeof(buf),
+                                _("The binding key sequence, that you choose,"
+                                  " is already used by
"
+                                  "<hilight>%s</hilight> action.
"
+                                  "Please choose another binding key"
+                                  " sequence."),
+                                act->action_name);
+                       e_util_dialog_show(_("Binding Key Error"), buf);
+                    }

 	       }
 	       _e_keybinding_keybind_shortcut_wnd_hide(cfdata);


pg_basebackup streaming: adjust version check msg

Commit d298b50a3b469c088bb40a4d36d38111b4cd574d by Heikki Linnakangas
requested that the version check message be updated at next release, suggesting
that the appropriate text would be “9.3 or later”. The logic used for the check
indicates that the correct text for 9.4 is “9.3 or 9.4”, since the logic would
cause this to fail for later releases.

--- src/bin/pg_basebackup/receivelog.c
+++ src/bin/pg_basebackup/receivelog.c
@@ -374,7 +374,7 @@
 		fprintf(stderr, _("%s: incompatible server version %s; streaming is only supported with server version %s\n"),
 				progname,
 				serverver ? serverver : "'unknown'",
-				"9.3");
+				"9.3 or 9.4");
 		return false;
 	}
 	return true;


Fixed issue 210.

Fixed issue 210.

git-svn-id: 003f22d385e25de9cff933a5ea4efd77cb5e7b28@1203 d6536bca-fef9-0310-8506-e4c0a848fbcf

--- Lib/stats/ranlib_all.c
+++ Lib/stats/ranlib_all.c
@@ -2124,6 +2124,7 @@
     *iseed2 = *(Xcg2+g-1);
 #undef numg
 }
+static void inrgcm(void);
 long ignlgi(void)
 /*
 **********************************************************************
@@ -2146,7 +2147,6 @@
 extern long Xm1,Xm2,Xa1,Xa2,Xcg1[],Xcg2[];
 extern long Xqanti[];
   */
-static void inrgcm(void);
 static long ignlgi,curntg,k,s1,s2,z;
 static long qqssd,qrgnin;
 /*


Fix typo in comment

Fix typo in comment

Author: Daniel Gustafsson <3d0f3b9ddcacec30c4008c5e030e6c13a478cb4f@yesql.se>

--- src/bin/pg_dump/pg_backup_custom.c
+++ src/bin/pg_dump/pg_backup_custom.c
@@ -4,7 +4,7 @@
  *
  *	Implements the custom output format.
  *
- *	The comments with the routined in this code are a good place to
+ *	The comments with the routines in this code are a good place to
  *	understand how to write a new format.
  *
  *	See the headers to pg_restore for more details.


cpu/esp32: enable _NANO_FORMATTED_IO for Espressif's GCC 8.4.0

error: pathspec 'cpu/esp32/include/newlib.h' did not match any file(s) known to git

--- cpu/esp32/include/newlib.h
+++ cpu/esp32/include/newlib.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 Gunar Schorcht
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @ingroup     cpu_esp32
+ * @{
+ *
+ * @file
+ * @brief       Wrapper for sys/features.h
+ *
+ * @author      Gunar Schorcht <gunar@schorcht.net>
+ *
+ * This file is just a wrapper for `newlib.h` to define `_NANO_FORMATTED_IO`
+ * correctly if the `newlib_nano` module is used. In difference to other
+ * toolchains, ESP32x toolchains don't use different `newlib.h` versions.
+ */
+
+#ifndef NEWLIB_H
+#define NEWLIB_H
+
+#include "kernel_defines.h"
+
+#ifndef DOXYGEN
+
+#if IS_USED(MODULE_NEWLIB_NANO)
+/* newlib nano formatted io is used */
+#define _NANO_FORMATTED_IO  1
+#endif
+
+#include_next <newlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DOXYGEN */
+#endif /* NEWLIB_H */
+/** @} */


Added parsing of date-time times stamps.

--- src/brics_3d/util/JSONTypecaster.h
+++ src/brics_3d/util/JSONTypecaster.h
@@ -85,7 +85,14 @@
 				if( stampModel.Get("@stamptype").AsString().compare("TimeStampUTCms") == 0 ) {

 					stamp = TimeStamp( stampModel.Get("stamp").AsDouble(), Units::MilliSecond);
+
 				} else if ( stampModel.Get("@stamptype").AsString().compare("TimeStampDate") == 0 ) {
+
+					string dateTime =  stampModel.Get("stamp").AsString();
+					struct tm tmlol;
+					strptime(dateTime.c_str(), "%Y-%m-%dT%H:%M:%SZ", &tmlol);
+					time_t t = mktime(&tmlol); // Seconds since epoche
+					stamp = TimeStamp(t, Units::Second);

 				} else {
 					LOG(ERROR) << "JSONTypecaster: Time stamp defeinition has unknown type @stamptype identifier";
@@ -98,7 +105,7 @@
 			LOG(ERROR) << "JSONTypecaster: entity has no stamp tag: " << stampTag;
 		}

-
+		LOG(DEBUG) << "JSONTypecaster: stamp = " << stamp.getSeconds();

 		return stamp;
 	}


nv50: fix vbo_static_attrib method size error

The VTX_ATTR_3/2/1F methods also had size 4 ...
a stupid copy/paste error.

--- src/gallium/drivers/nv50/nv50_vbo.c
+++ src/gallium/drivers/nv50/nv50_vbo.c
@@ -313,18 +313,18 @@
 		so_data  (so, fui(v[3]));
 		break;
 	case 3:
-		so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 4);
+		so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 3);
 		so_data  (so, fui(v[0]));
 		so_data  (so, fui(v[1]));
 		so_data  (so, fui(v[2]));
 		break;
 	case 2:
-		so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 4);
+		so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 2);
 		so_data  (so, fui(v[0]));
 		so_data  (so, fui(v[1]));
 		break;
 	case 1:
-		so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 4);
+		so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 1);
 		so_data  (so, fui(v[0]));
 		break;
 	default:


pipe: Add PIPE_OS_HURD

pipe: Add PIPE_OS_HURD

One tiny step toward porting Gallium to the GNU/Hurd kernel
(and fixing Debian bug #585618).

Signed-off-by: Corbin Simpson <6f93ebc715fb8f8332b02f5c63afa6920b9d43d8@gmail.com>

--- src/gallium/include/pipe/p_config.h
+++ src/gallium/include/pipe/p_config.h
@@ -143,6 +143,11 @@
 #if defined(__NetBSD__)
 #define PIPE_OS_NETBSD
 #define PIPE_OS_BSD
+#define PIPE_OS_UNIX
+#endif
+
+#if defined(__GNU__)
+#define PIPE_OS_HURD
 #define PIPE_OS_UNIX
 #endif


add strdup func to fix segfault on windows

--- autoload/fuzzycomt.c
+++ autoload/fuzzycomt.c
@@ -34,6 +34,13 @@
         match = findmatch(path, abbrev, mmode);
 		matches[i] = match;
     }
+}
+
+char *strdup (const char *s) {
+    char *d = malloc (strlen (s) + 1);   // Space for length plus nul
+    if (d == NULL) return NULL;          // No memory
+    strcpy (d,s);                        // Copy the characters
+    return d;                            // Return the new string
 }

 char *slashsplit(char *line)


More work on chest placement

More work on chest placement

--- common/dwr.c
+++ common/dwr.c
@@ -657,14 +657,10 @@
         uint8_t y, uint8_t tile)
 {
     BOOL is_dungeon;
+    uint8_t oldval;
     size_t offset = (size_t)y * (rom->map.meta[town].width+1) + x;
     size_t data_addr = ((*(uint16_t*)(&rom->map.meta[town].pointer)) & 0x7fff) +
         offset/2;
-
-    printf("Map: %d, Width: %d, Height: %d, X: %d, Y: %d\n", town,
-            rom->map.meta[town].width, rom->map.meta[town].height, x, y);
-    printf("Addr: %lX, offset: %ld, modified: %lX\n",
-            data_addr, offset, data_addr + offset/2);

     if (x > rom->map.meta[town].width || y > rom->map.meta[town].height) {
         printf("Map index (%d, %d) out of bounds, skipping tile setting...\n",
@@ -678,6 +674,7 @@
     /* Preserve the MSB for dungeon tiles. It seems to contain roof data for
      * towns?  */
     is_dungeon = is_dungeon_tileset(town);
+    oldval = rom->content[data_addr];
     if (offset % 2) {
         if (is_dungeon) {
             rom->content[data_addr] &= 0xf8;
@@ -693,6 +690,14 @@
         }
         rom->content[data_addr] |= tile << 4;
     }
+
+    /* TODO: remove this before release */
+    printf("Map: %d, Width: %d, Height: %d, X: %d, Y: %d, tile: %X\n", town,
+            rom->map.meta[town].width, rom->map.meta[town].height, x, y, tile);
+    printf("Addr: %lX, offset: %ld, modified: %lX from %X to %X\n",
+            data_addr, offset, data_addr + offset/2, oldval,
+            rom->content[data_addr]);
+
 }

 static int chest_bin(dw_map_index map) {
@@ -720,7 +725,35 @@
             return -1;
     }
 }
-
+
+/** Checks to see if a chest already exists at the current x/y coordinates.
+ * This will avoid conflicts since 2 chests cannot exist at the same
+ * coordinates where the player can travel to both locations without crossing
+ * the overwold. With stair shuffle coming, lets just avoid all conflicts.
+ *
+ * @param rom The rom struct
+ * @param x The x coordinate
+ * @param y The y coordinate
+ * @param until The number of chests to check from the beginning.
+ *
+ * @return A pointer to the conflicting chest.
+ */
+static dw_chest *chest_at(dw_rom *rom, uint8_t x, uint8_t y, size_t until) {
+    dw_chest *chest;
+    dw_chest *stop = rom->chests + until;
+    for (chest = rom->chests; chest < stop; chest++) {
+        if(chest->x == x && chest->y == y) {
+            return chest;
+        }
+    }
+    return NULL;
+}
+
+/**
+ * Randomizes the placment of chests to a subset of predetermined locations
+ *
+ * @param rom The rom struct
+ */
 static void move_chests(dw_rom *rom)
 {
     size_t i, j;
@@ -731,83 +764,95 @@
 //         {TANTEGEL_THRONE_ROOM,  4,  4}, /* vanilla */
 //         {TANTEGEL_THRONE_ROOM,  5,  4}, /* vanilla */
 //         {TANTEGEL_THRONE_ROOM,  6,  1}, /* vanilla */
-        {TANTEGEL            ,  1, 13}, /* vanilla */
-        {TANTEGEL            ,  2, 13},
-        {TANTEGEL            ,  3, 13}, /* vanilla */
-        {TANTEGEL            ,  1, 14},
-        {TANTEGEL            ,  2, 14}, /* vanilla */
-        {TANTEGEL            ,  3, 14},
-        {TANTEGEL            ,  1, 15}, /* vanilla */
-        {TANTEGEL            ,  2, 15},
-        {TANTEGEL            ,  3, 15}, /* vanilla */
-        {TANTEGEL            , 16, 15},
-        {TANTEGEL            , 24, 21},
-        {TANTEGEL_BASEMENT   ,  4,  5}, /* vanilla */
-        {TANTEGEL_BASEMENT   ,  4,  4},
-        {TANTEGEL_BASEMENT   ,  5,  5},
-        {BRECCONARY          ,  3, 21},
-//         {BRECCONARY          , 21,  3},
-        {ERDRICKS_CAVE       ,  9,  0},
-        {ERDRICKS_CAVE_2     ,  9,  0},
-        {ERDRICKS_CAVE_2     ,  9,  3}, /* vanilla */
-        {GARINHAM            ,  4,  5},
-        {GARINHAM            ,  8,  5}, /* vanilla */
-        {GARINHAM            ,  8,  6}, /* vanilla */
-        {GARINHAM            ,  9,  5}, /* vanilla */
-        {GARINHAM            , 18, 18}, /* LOCK 16, 18 */
-        {GARINS_GRAVE_1      , 11,  0}, /* vanilla */
-        {GARINS_GRAVE_1      , 12,  0}, /* vanilla */
-        {GARINS_GRAVE_1      , 13,  0}, /* vanilla */
-        {GARINS_GRAVE_1      ,  0, 14},
-        {GARINS_GRAVE_1      ,  7,  5},
-        {GARINS_GRAVE_1      ,  4, 15},
-        {GARINS_GRAVE_3      ,  1,  1}, /* vanilla */
-        {GARINS_GRAVE_3      , 13,  6}, /* vanilla */
-        {GARINS_GRAVE_3      , 13, 10},
-        {GARINS_GRAVE_3      , 17, 17},
-        {KOL                 , 22,  1}, /* LOCK 20, 2 */
-        {SWAMP_CAVE          ,  5,  0},
-        {SWAMP_CAVE          ,  4, 19},
-        {SWAMP_CAVE          ,  5, 29},
-        {RIMULDAR            , 24, 23}, /* vanilla */
-        {MOUNTAIN_CAVE       , 13,  5}, /* vanilla */
-        {MOUNTAIN_CAVE       , 13,  9},
-        {MOUNTAIN_CAVE_2     ,  1,  1},
-        {MOUNTAIN_CAVE_2     , 13,  9},
-        {MOUNTAIN_CAVE_2     ,  0,  3},
-        {MOUNTAIN_CAVE_2     ,  1,  6}, /* vanilla */
-        {MOUNTAIN_CAVE_2     ,  2, 11},
-        {MOUNTAIN_CAVE_2     ,  2,  2}, /* vanilla */
-        {MOUNTAIN_CAVE_2     ,  3,  2}, /* vanilla */
-        {MOUNTAIN_CAVE_2     , 10,  9}, /* vanilla */
-        {HAUKSNESS           ,  6,  9}, /*  LOCK 10, 8  */
-        {CANTLIN             ,  2, 27}, /*  LOCK 3, 24 */
-        {CANTLIN             , 12,  2}, /*  LOCK 10, 4  */
-        {CHARLOCK_CAVE_1     , 19,  9},
-        {CHARLOCK_CAVE_1     ,  8,  6},
-        {CHARLOCK_CAVE_1     , 19,  6},
-        {CHARLOCK_CAVE_2     ,  5,  5}, /* vanilla */
-        {CHARLOCK_CAVE_3     ,  3,  8},
-        {CHARLOCK_CAVE_5     ,  2,  0},
-        {CHARLOCK_CAVE_6     ,  9,  0},
-        {CHARLOCK_THRONE_ROOM,  5,  2}, /* LOCK 4, 9 */
+        {TANTEGEL,              1, 13}, /* vanilla */
+        {TANTEGEL,              2, 13},
+        {TANTEGEL,              3, 13}, /* vanilla */
+        {TANTEGEL,              1, 14},
+        {TANTEGEL,              2, 14}, /* vanilla */
+        {TANTEGEL,              3, 14},
+        {TANTEGEL,              1, 15}, /* vanilla */
+        {TANTEGEL,              2, 15},
+        {TANTEGEL,              3, 15}, /* vanilla */
+        {TANTEGEL,             16, 15},
+        {TANTEGEL,             24, 21},
+        {TANTEGEL_BASEMENT,     4,  5}, /* vanilla */
+        {TANTEGEL_BASEMENT,     4,  8},
+        {TANTEGEL_BASEMENT,     5,  8},
+        {BRECCONARY,            3, 21},
+        {BRECCONARY,           10, 23},
+//         {BRECCONARY,           21,  3},
+        {ERDRICKS_CAVE,         9,  0},
+        {ERDRICKS_CAVE_2,       2,  9},
+        {ERDRICKS_CAVE_2,       9,  3}, /* vanilla */
+        {GARINHAM,              4,  5},
+        {GARINHAM,              8,  5}, /* vanilla */
+        {GARINHAM,              8,  6}, /* vanilla */
+        {GARINHAM,              9,  5}, /* vanilla */
+        {GARINHAM,             18, 18},
+        {GARINS_GRAVE_1,       11,  0}, /* vanilla */
+        {GARINS_GRAVE_1,       12,  0}, /* vanilla */
+        {GARINS_GRAVE_1,       13,  0}, /* vanilla */
+        {GARINS_GRAVE_1,        0, 14},
+        {GARINS_GRAVE_1,        7,  5},
+        {GARINS_GRAVE_1,        4, 15},
+        {GARINS_GRAVE_3,        1,  1}, /* vanilla */
+        {GARINS_GRAVE_3,       13,  6}, /* vanilla */
+        {GARINS_GRAVE_3,       13, 10},
+        {GARINS_GRAVE_3,       17, 17},
+        {KOL,                  22,  1},
+        {KOL,                   3, 13},
+        {SWAMP_CAVE,            5,  0},
+        {SWAMP_CAVE,            4, 19},
+        {SWAMP_CAVE,            5, 29},
+        {RIMULDAR,             24, 23}, /* vanilla */
+        {RIMULDAR,             17, 23},
+        {RIMULDAR,              3, 20},
+        {MOUNTAIN_CAVE,        13,  5}, /* vanilla */
+        {MOUNTAIN_CAVE,        13,  9},
+        {MOUNTAIN_CAVE_2,       1,  1},
+        {MOUNTAIN_CAVE_2,      13,  9},
+        {MOUNTAIN_CAVE_2,       0,  3},
+        {MOUNTAIN_CAVE_2,       1,  6}, /* vanilla */
+        {MOUNTAIN_CAVE_2,       2, 11},
+        {MOUNTAIN_CAVE_2,       2,  2}, /* vanilla */
+        {MOUNTAIN_CAVE_2,       3,  2}, /* vanilla */
+        {MOUNTAIN_CAVE_2,      10,  9}, /* vanilla */
+        {HAUKSNESS,             6,  9},
+        {CANTLIN,               2, 27},
+        {CANTLIN,              12,  2},
+        {CHARLOCK_CAVE_1,      19,  9},
+        {CHARLOCK_CAVE_1,       2, 17},
+        {CHARLOCK_CAVE_1,       8,  6},
+        {CHARLOCK_CAVE_1,      11,  6},
+        {CHARLOCK_CAVE_1,      19,  6},
+        {CHARLOCK_CAVE_2,       5,  5}, /* vanilla */
+        {CHARLOCK_CAVE_3,       3,  8},
+        {CHARLOCK_CAVE_4,       6,  4},
+        {CHARLOCK_CAVE_5,       2,  0},
+        {CHARLOCK_CAVE_6,       9,  0},
+        {CHARLOCK_THRONE_ROOM,  5,  2},
         {CHARLOCK_THRONE_ROOM,  6, 12},
-        {CHARLOCK_THRONE_ROOM,  8, 12}, /* LOCK 7, 22 */
+        {CHARLOCK_THRONE_ROOM,  8, 12},
         {CHARLOCK_THRONE_ROOM, 11, 11}, /* vanilla */
         {CHARLOCK_THRONE_ROOM, 11, 12}, /* vanilla */
         {CHARLOCK_THRONE_ROOM, 11, 13}, /* vanilla */
+        {CHARLOCK_THRONE_ROOM, 12, 11},
         {CHARLOCK_THRONE_ROOM, 12, 12}, /* vanilla */
         {CHARLOCK_THRONE_ROOM, 12, 13}, /* vanilla */
+        {CHARLOCK_THRONE_ROOM, 13, 11},
+        {CHARLOCK_THRONE_ROOM, 13, 12},
         {CHARLOCK_THRONE_ROOM, 13, 13}, /* vanilla */
         {CHARLOCK_THRONE_ROOM, 22, 26},
     };

     uint8_t new_doors[][3] = {
-        {GARINHAM            , 16, 18},
-        {KOL                 , 20,  2},
-        {HAUKSNESS           , 10,  8},
-        {CANTLIN             ,  3, 24},
-        {CANTLIN             , 10,  4},
+        {BRECCONARY,            8, 23},
+        {GARINHAM,             16, 18},
+        {KOL,                  20,  2},
+        {RIMULDAR,             17, 21},
+        {HAUKSNESS,            10,  8},
+        {CANTLIN,               3, 24},
+        {CANTLIN,              10,  4},
         {CHARLOCK_THRONE_ROOM,  4,  9},
         {CHARLOCK_THRONE_ROOM,  7, 22},
     };
@@ -816,6 +861,7 @@
         return;
     }

+    printf("Removing all chests...\n");
     for (i=0; i < sizeof(chest_spots) / 3; i++) {
         chest_spot = chest_spots[i];
         if (is_dungeon_tileset(chest_spot[0])) {
@@ -826,6 +872,7 @@
                     TOWN_TILE_BRICK);
         }
     }
+    printf("Adding doors...\n");
     for (i=0; i < sizeof(new_doors) / 3; i++) {
         new_door = new_doors[i];
         if (is_dungeon_tileset(new_door[0])) {
@@ -836,15 +883,25 @@
                     TOWN_TILE_DOOR);
         }
     }
-    mt_shuffle(chest_spots, sizeof(chest_spots)/3, 3);
-    for (i=0, j=0; i < 31; i++, j++) {
+    printf("Adding back chests...\n");
+chest_placement_retry:
+    mt_shuffle(chest_spots, sizeof(chest_spots) / 3, 3);
+    for (i=0, j=0; i < CHEST_COUNT; i++, j++) {
         map = rom->chests[i].map;
          /* don't mess with these */
         if (map == TANTEGEL_THRONE_ROOM || map == NORTHERN_SHRINE)
             continue;
+        while (chest_at(rom, chest_spots[j][1], chest_spots[j][2], i+3)) {
+            j++;
+        }
         bin = chest_bin(chest_spots[j][0]);
         while (bin >= 0 && chest_bins[j] > 8) {
             bin = chest_bin(chest_spots[++j][0]);
+        }
+        if (j >= sizeof(chest_spots) / 3) {
+            /* this should never happen, but just in case */
+            printf("Something went wront, retrying chest placement...\n");
+            goto chest_placement_retry;
         }
         chest_bins[bin]++;
         rom->chests[i].map = chest_spots[j][0];
@@ -1859,7 +1916,7 @@
     /* replace the charlock loop stairs with some for tantegel */
     vpatch(rom, 0xf437, 3, 5, 1, 8);
     vpatch(rom, 0xf4d0, 3, 4, 1, 7);
-    set_dungeon_tile(rom, CHARLOCK_CAVE_6, 20, 9, DUNGEON_TILE_BRICK);
+    set_dungeon_tile(rom, CHARLOCK_CAVE_6, 9, 0, DUNGEON_TILE_BRICK);
     /* Sets the encounter rate of Zone 0 to be the same as other zones. */
     vpatch(rom, 0xcebf, 3, 0x4c, 0x04, 0xcf);  /* skip over the zone 0 code */
     vpatch(rom, 0xe260, 1, 0);  /* set death necklace chance to 100% */


simplified modular hnf

simplified modular hnf

--- fmpz_mat/hnf_modular.c
+++ fmpz_mat/hnf_modular.c
@@ -27,12 +27,13 @@

 void fmpz_mat_hnf_modular(fmpz_mat_t H, const fmpz_mat_t A, const fmpz_t D)
 {
-    slong j, j2, i, k;
+    slong j, i, k;
     fmpz_t R, R2, d, u, v, r1d, r2d, b, q;
+
+    fmpz_mat_set(H, A);

     fmpz_init_set(R, D);
     fmpz_init(R2);
-    fmpz_mat_set(H, A);
     fmpz_init(u);
     fmpz_init(u);
     fmpz_init(v);
@@ -42,59 +43,59 @@
     fmpz_init(b);
     fmpz_init(q);

-    for (j = 0, k = 0; j != A->c; j++, k++)
+    for (k = 0; k != A->c; k++)
     {
         fmpz_fdiv_q_2exp(R2, R, 1);

-        if (fmpz_is_zero(fmpz_mat_entry(H, k, j)))
-            fmpz_set(fmpz_mat_entry(H, k, j), R);
+        if (fmpz_is_zero(fmpz_mat_entry(H, k, k)))
+            fmpz_set(fmpz_mat_entry(H, k, k), R);
         for (i = k + 1; i != A->r; i++)
         {
             /* reduce row i with row k mod R */
-            if (fmpz_is_zero(fmpz_mat_entry(H, i, j)))
+            if (fmpz_is_zero(fmpz_mat_entry(H, i, k)))
                 continue;
-            fmpz_xgcd(d, u, v, fmpz_mat_entry(H, k, j),
-                    fmpz_mat_entry(H, i, j));
-            fmpz_divexact(r1d, fmpz_mat_entry(H, k, j), d);
-            fmpz_divexact(r2d, fmpz_mat_entry(H, i, j), d);
-            for (j2 = j; j2 < A->c; j2++)
+            fmpz_xgcd(d, u, v, fmpz_mat_entry(H, k, k),
+                    fmpz_mat_entry(H, i, k));
+            fmpz_divexact(r1d, fmpz_mat_entry(H, k, k), d);
+            fmpz_divexact(r2d, fmpz_mat_entry(H, i, k), d);
+            for (j = k; j < A->c; j++)
             {
-                fmpz_mul(b, u, fmpz_mat_entry(H, k, j2));
-                fmpz_addmul(b, v, fmpz_mat_entry(H, i, j2));
-                fmpz_mul(fmpz_mat_entry(H, i, j2), r1d,
-                        fmpz_mat_entry(H, i, j2));
-                fmpz_submul(fmpz_mat_entry(H, i, j2), r2d,
-                        fmpz_mat_entry(H, k, j2));
-                fmpz_mod(fmpz_mat_entry(H, i, j2), fmpz_mat_entry(H, i, j2), R);
-                if (fmpz_cmp(fmpz_mat_entry(H, i, j2), R2) > 0)
-                    fmpz_sub(fmpz_mat_entry(H, i, j2),
-                            fmpz_mat_entry(H, i, j2), R);
-                fmpz_set(fmpz_mat_entry(H, k, j2), b);
-                fmpz_mod(fmpz_mat_entry(H, k, j2), fmpz_mat_entry(H, k, j2), R);
-                if (fmpz_cmp(fmpz_mat_entry(H, k, j2), R2) > 0)
-                    fmpz_sub(fmpz_mat_entry(H, k, j2),
-                            fmpz_mat_entry(H, k, j2), R);
+                fmpz_mul(b, u, fmpz_mat_entry(H, k, j));
+                fmpz_addmul(b, v, fmpz_mat_entry(H, i, j));
+                fmpz_mul(fmpz_mat_entry(H, i, j), r1d,
+                        fmpz_mat_entry(H, i, j));
+                fmpz_submul(fmpz_mat_entry(H, i, j), r2d,
+                        fmpz_mat_entry(H, k, j));
+                fmpz_mod(fmpz_mat_entry(H, i, j), fmpz_mat_entry(H, i, j), R);
+                if (fmpz_cmp(fmpz_mat_entry(H, i, j), R2) > 0)
+                    fmpz_sub(fmpz_mat_entry(H, i, j),
+                            fmpz_mat_entry(H, i, j), R);
+                fmpz_set(fmpz_mat_entry(H, k, j), b);
+                fmpz_mod(fmpz_mat_entry(H, k, j), fmpz_mat_entry(H, k, j), R);
+                if (fmpz_cmp(fmpz_mat_entry(H, k, j), R2) > 0)
+                    fmpz_sub(fmpz_mat_entry(H, k, j),
+                            fmpz_mat_entry(H, k, j), R);
             }
         }

-        fmpz_xgcd(d, u, v, fmpz_mat_entry(H, k, j), R);
-        for (j2 = j; j2 < A->c; j2++)
+        fmpz_xgcd(d, u, v, fmpz_mat_entry(H, k, k), R);
+        for (j = k; j < A->c; j++)
         {
-            fmpz_mul(fmpz_mat_entry(H, k, j2), u,
-                fmpz_mat_entry(H, k, j2));
-            fmpz_mod(fmpz_mat_entry(H, k, j2), fmpz_mat_entry(H, k, j2), R);
+            fmpz_mul(fmpz_mat_entry(H, k, j), u,
+                fmpz_mat_entry(H, k, j));
+            fmpz_mod(fmpz_mat_entry(H, k, j), fmpz_mat_entry(H, k, j), R);
         }
-        if (fmpz_is_zero(fmpz_mat_entry(H, k, j)))
-            fmpz_set(fmpz_mat_entry(H, k, j), R);
-        /* reduce higher entries of column j with row k */
+        if (fmpz_is_zero(fmpz_mat_entry(H, k, k)))
+            fmpz_set(fmpz_mat_entry(H, k, k), R);
+        /* reduce higher entries of column k with row k */
         for (i = k - 1; i >= 0; i--)
         {
-            fmpz_fdiv_q(q, fmpz_mat_entry(H, i, j),
-                    fmpz_mat_entry(H, k, j));
-            for (j2 = j; j2 < A->c; j2++)
+            fmpz_fdiv_q(q, fmpz_mat_entry(H, i, k),
+                    fmpz_mat_entry(H, k, k));
+            for (j = k; j < A->c; j++)
             {
-                fmpz_submul(fmpz_mat_entry(H, i, j2), q,
-                        fmpz_mat_entry(H, k, j2));
+                fmpz_submul(fmpz_mat_entry(H, i, j), q,
+                        fmpz_mat_entry(H, k, j));
             }
         }
         fmpz_divexact(R, R, d);


fan: fix fanset console command

fan: fix fanset console command

This fixes how the fanset console command parses its arguments. The
original parsing would use the fan number as the RPM/duty cycle
percentage when two arguments were given on a single fan system. Two
arguments are now always treated as (fan number, RPM/duty cycle). On a
single fan system, the fan number may be omitted. Additional arguments
are rejected.

BRANCH=none
BUG=none
TEST=verified fanset console command controls fan

Change-Id: Ia6094354cbbc99c8bfcdb9dd9f227f75dc34507a
Signed-off-by: Caveh Jalali <08e24a66aefda7a55ca7d73f8903e0fb16eec763@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2689498
Reviewed-by: Keith Short <f6d578f97033c25f1206cb57d52f358974c82954@chromium.org>
Commit-Queue: Keith Short <f6d578f97033c25f1206cb57d52f358974c82954@chromium.org>

--- common/fan.c
+++ common/fan.c
@@ -218,6 +218,7 @@

 static int cc_fanset(int argc, char **argv)
 {
+	const char *rpm_str;
 	int rpm;
 	char *e;
 	int fan = 0;
@@ -228,21 +229,24 @@
 	}

 	if (fan_count > 1) {
-		if (argc < 2) {
+		if (argc < 3) {
 			ccprintf("fan number is required as the first arg\n");
 			return EC_ERROR_PARAM_COUNT;
 		}
+	}
+
+	if (argc == 3) {
 		fan = strtoi(argv[1], &e, 0);
 		if (*e || fan >= fan_count)
 			return EC_ERROR_PARAM1;
-		argc--;
-		argv++;
-	}
-
-	if (argc < 2)
+		rpm_str = argv[2];
+	} else if (argc == 2) {
+		rpm_str = argv[1];
+	} else {
 		return EC_ERROR_PARAM_COUNT;
-
-	rpm = strtoi(argv[2], &e, 0);
+	}
+
+	rpm = strtoi(rpm_str, &e, 0);
 	if (*e == '%') {		/* Wait, that's a percentage */
 		ccprintf("Fan rpm given as %d%%\n", rpm);
 		if (rpm < 0)
@@ -270,7 +274,7 @@
 	return EC_SUCCESS;
 }
 DECLARE_CONSOLE_COMMAND(fanset, cc_fanset,
-			"{fan} (rpm | pct%)",
+			"[fan] (rpm | pct%)",
 			"Set fan speed");

 static int cc_fanduty(int argc, char **argv)


Implementation Update

Implementation Update

Fixed a couple bugs and optimized the code

--- patterns/Forza.h
+++ patterns/Forza.h
@@ -1,134 +1,156 @@
-#ifndef FORZA_H
-#define FORZA_H
+#ifndef Forza_h__
+#define Forza_h__

 struct PatternData
 {
-    uint32_t		Count;
-    __m128i		Data[32];
+	uint32_t	Count;
+	uint32_t	Length[16];
+	uint32_t	Mask[16];
+	uint32_t	Offset[16];
+	__m128i		Value[16];
 };

-void GeneratePatternArray( const char* Signature, const char* Mask, PatternData* Out )
+void GeneratePatternArray(const char* Signature, const char* Mask, PatternData* Out)
 {
-    auto len = strlen( Mask );
-    auto count = len;
+	auto len = strlen(Mask);
+	auto len2 = 0;

-    if (count < 16 || count % 16)
-        count = (count / 16) + 1;
-    else
-        count /= 16;
+	Out->Count = 0;

-    Out->Count = count;
+	for (auto i = 0; i < len; i++)
+	{
+		if (Mask[i] != 'x')
+			continue;

-    for (auto i = 0; i < count; i++)
-        Out->Data[i] = _mm_loadu_si128( (const __m128i*)Signature + i );
+		auto mask_begin = 0;
+		for (auto j = i; j < len; j++)
+		{
+			if (Mask[j] == '?')
+				break;
+
+			mask_begin++;
+		}
+
+		len2 = mask_begin;
+
+		if (len2 + i > len)
+			len2 = len - i;
+
+		Out->Value[Out->Count]		= _mm_loadu_si128((const __m128i*)(Signature + i));
+		Out->Length[Out->Count]		= len2;
+		Out->Offset[Out->Count]		= i;
+		Out->Count					+= 1;
+		i							+= len2;
+	}
+
+	for (auto j = 1; j < Out->Count; j++)
+		Out->Mask[j - 1] = Out->Offset[j] - (Out->Offset[j - 1] + Out->Length[j - 1]);
 }

-uint8_t* SubScan( const uint8_t* Data, uint32_t Max, PatternData* Patterns, const char* Signature, const char* Mask )
+__forceinline uint8_t* Find(const uint8_t* Data, const uint32_t Length, const char* Signature, const char* Mask, bool ZeroCheck = true)
 {
-    const auto s = strlen( Mask );
+	PatternData d;
+	GeneratePatternArray(Signature, Mask, &d);

-    for (auto i = 0; i < Patterns->Count; i++)
-    {
-        if (Data[s - 1] != Signature[s - 1])
-            return nullptr;
+	const auto ml			= strlen(Mask);
+	const auto branches		= Length / 32;
+	const auto end			= Data + Length - ml;

-        auto k = _mm_loadu_si128( (const __m128i*)Data + i );
+	for (auto i = 0; i < branches; i++)
+	{
+		auto k = _mm256_load_si256((const __m256i*)Data + i);

-        for (auto j = 0; j < s; j++)
-        {
-            if (Mask[(i * 16) + j] != 'x')
-                Patterns->Data[i].m128i_u8[j] = k.m128i_u8[j];
-        }
+		if (ZeroCheck && _mm256_test_all_zeros(k, k) == 1)
+			continue;

-        if (i + 1 >= Patterns->Count)
-        {
-            auto cutoff = ((i + 1) * 16) - s;
+		auto WithinRegion = [](const __m256i Pointer, PatternData* Patterns)
+		{
+			auto f = _mm_cmpestri(Patterns->Value[0], Patterns->Length[0], _mm256_extractf128_si256(Pointer, 0), 16, _SIDD_CMP_EQUAL_ORDERED);

-            for (auto j = 0; j <= cutoff; j++)
-                Patterns->Data[i].m128i_u8[16 - j] = k.m128i_u8[16 - j];
-        }
+			if (f == 16)
+				f += _mm_cmpestri(Patterns->Value[0], Patterns->Length[0], _mm256_extractf128_si256(Pointer, 1), 16, _SIDD_CMP_EQUAL_ORDERED);

-        auto cmp = _mm_xor_si128( k, Patterns->Data[i] );
+			return f;
+		};

-        if (_mm_test_all_zeros( cmp, cmp ) != 1)
-            return nullptr;
+		auto ptr = Data + i * 32;

-        if (i + 1 >= Patterns->Count)
-            return (uint8_t*)Data;
-    }
+	Search:
+		auto f = WithinRegion(k, &d);

-    return nullptr;
+		if (f == 32)
+			continue;
+
+		ptr += f;
+
+		if (ptr + ml >= end)
+			return nullptr;
+
+		auto ContainsAllSubs = [](const uint8_t* Pointer, PatternData* Patterns)
+		{
+			auto p = Pointer;
+
+			for (auto i = 0; i < Patterns->Count; i++)
+			{
+				auto k = _mm_cmpestri(Patterns->Value[i], Patterns->Length[i], _mm_loadu_si128((const __m128i*)p), Patterns->Length[i], _SIDD_CMP_EQUAL_EACH);
+
+				if (k != 0)
+					return false;
+
+				p += Patterns->Length[i] + Patterns->Mask[i];
+			}
+
+			return true;
+		};
+
+		if (ptr[ml - 1] == Signature[ml - 1] && ContainsAllSubs(ptr, &d))
+			return (uint8_t*)ptr;
+
+		ptr++;
+
+		if (ptr + 16 >= end)
+			return nullptr;
+
+		k = _mm256_load_si256((const __m256i*)ptr);
+		goto Search;
+	}
+
+	return nullptr;
 }

-uint8_t* Find( const uint8_t* Data, const uint32_t Length, const char* Signature, const char* Mask )
+struct Forza : public BenchBase
 {
-    PatternData d;
-    GeneratePatternArray( Signature, Mask, &d );
+	virtual void init(Tests test)
+	{
+		switch (test)
+		{
+		case Tests::First:
+			Pattern_	= "\x45\x43\x45\x55\x33\x9a\xfa\x00\x00\x00\x00\x45\x68\x21";
+			Mask_		= "xxxxxxx????xxx";
+			break;
+		case Tests::Second:
+			Pattern_	= "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xbb\xaa\x00\x00\x00\x00\x45\x68\x21";
+			Mask_		= "xxxxxxxxxxx????xxx";
+			break;
+		default:
+			break;
+		}
+	}

-    const auto nl = strlen( Signature );
-    const auto branches = Length / 32;
-    const auto first = d.Data[0];
-    const auto end = Data + Length - nl;
+	virtual LPVOID runOne(PBYTE baseAddress, DWORD size)
+	{
+		return Find(baseAddress, size, Pattern_, Mask_, true);
+	}

-    for (auto i = 0; i < branches - 1; i++)
-    {
-        auto k = _mm256_load_si256( (const __m256i*)Data + i );
+	virtual const char* name() const
+	{
+		return "Forza";
+	}

-        if (_mm256_test_all_zeros( k, k ) == 1)
-            continue;
-
-        auto f = _mm_cmpestri( first, nl, _mm_loadu_si128( (const __m128i*)(Data + i * 32) ), 16, _SIDD_CMP_EQUAL_ORDERED );
-
-        if (f == 16)
-        {
-            f = _mm_cmpestri( first, nl, _mm_loadu_si128( (const __m128i*)(Data + i * 32 + 16) ), 16, _SIDD_CMP_EQUAL_ORDERED );
-
-            if (f == 16)
-                continue;
-
-            f += 16;
-        }
-
-        uint8_t* p = (uint8_t*)(Data + (i * 32) + f);
-        p = SubScan( p, static_cast<uint32_t>(end - p), &d, Signature, Mask );
-
-        if (p != nullptr)
-            return p;
-    }
-
-    return nullptr;
-}
-
-struct FORZA : public BenchBase
-{
-    virtual void init( Tests test )
-    {
-        switch (test)
-        {
-        case Tests::First:
-            pattern = "\x45\x43\x45\x55\x33\x9a\xfa\x00\x00\x00\x00\x45\x68\x21";
-            mask = "xxxxxxx????xxx";
-            break;
-        case Tests::Second:
-            pattern = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xbb\xaa\x00\x00\x00\x00\x45\x68\x21";
-            mask = "xxxxxxxxxxx????xxx";
-            break;
-        }
-    }
-
-    virtual LPVOID runOne( PBYTE baseAddress, DWORD size )
-    {
-        return Find( baseAddress, size, pattern, mask );
-    }
-    virtual const char* name() const
-    {
-        return "Forza";
-    }
-
-    char* pattern;
-    char* mask;
+	char* Pattern_;
+	char* Mask_;
 };

-REGISTER( FORZA );
+REGISTER(Forza);

-#endif // FORZA_H
+#endif // Forza_h__


add interupt handler for clean shutdown

add interupt handler for clean shutdown

--- weather_scraper/weather_scraper.c
+++ weather_scraper/weather_scraper.c
@@ -194,10 +194,20 @@
     *(end + 1) = '\0';
 }

+static void sigint_handler (int sig) {
+    _alive = 0;
+}
+
 // main function
 int main (int argc, char* argv[]) {
     int status = 0;
     struct mg_mgr mgr;
+    struct sigaction handler;
+
+    _alive             = 1;
+    handler.sa_handler = sigint_handler;
+    sigaction (SIGINT, &handler, NULL);
+
     mg_mgr_init (&mgr, NULL);

     status = config_get ();


Delete unused class MockVCMFrameTypeCallback

Unused since https://codereview.webrtc.org/2755803004

Bug: None
Change-Id: I5c5180fa990235f6353dd972cf4cc05676730a3b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132541
Reviewed-by: Rasmus Brandt <9545de3a34b925a736ae2b5ee593f3033f743a28@webrtc.org>
Commit-Queue: Niels Moller <0057859e47d61d90529d0f66d9ef692cefedb46a@webrtc.org>
Cr-Commit-Position: 972c6d2dc6dd5efdad1377c0d224e03eb8f276f7@{#27562}

--- modules/video_coding/include/mock/mock_vcm_callbacks.h
+++ modules/video_coding/include/mock/mock_vcm_callbacks.h
@@ -15,11 +15,6 @@
 #include "test/gmock.h"

 namespace webrtc {
-
-class MockVCMFrameTypeCallback : public VCMFrameTypeCallback {
- public:
-  MOCK_METHOD0(RequestKeyFrame, int32_t());
-};

 class MockPacketRequestCallback : public VCMPacketRequestCallback {
  public:


Fixed CB-440 - (LLVM-GCC only) Wrong number of arguments specified for 'deprecated' attribute

--- CordovaLib/Classes/CDVURLProtocol.h
+++ CordovaLib/Classes/CDVURLProtocol.h
@@ -22,7 +22,13 @@
 @interface CDVURLProtocol : NSURLProtocol {
 }

-+ (void) registerPGHttpURLProtocol __attribute__ ((deprecated("Renamed - use registerUrlProtocol instead.")));
++ (void) registerPGHttpURLProtocol
+#ifdef __clang__
+    __attribute__ ((deprecated("Renamed - use registerUrlProtocol instead.")));
+#else
+    __attribute__ ((deprecated()));
+#endif
+
 + (void) registerURLProtocol;

 @end


kmscompositemixer: Replace KmsCompositeMixerPortData for KmsGenericStructure

Change-Id: I1ea6bdb74089c93db98ec597893c0a048be78273

--- src/gst-plugins/kmscompositemixer.c
+++ src/gst-plugins/kmscompositemixer.c
@@ -17,6 +17,7 @@
 #endif

 #include "kmscompositemixer.h"
+#include "kmsgenericstructure.h"
 #include <commons/kmsagnosticcaps.h>
 #include <commons/kmshubport.h>
 #include <commons/kmsloop.h>
@@ -50,6 +51,20 @@
 #define VIDEO_SINK_PAD_NAME_COMP VIDEO_SINK_PAD_PREFIX_COMP "%u"
 #define AUDIO_SRC_PAD_NAME_COMP AUDIO_SRC_PAD_PREFIX_COMP "%u"
 #define VIDEO_SRC_PAD_NAME_COMP VIDEO_SRC_PAD_PREFIX_COMP "%u"
+#define ID "id"
+#define MIXER "mixer"
+#define VIDEO_MIXER_PAD "video_mixer_pad"
+#define CAPSFILTER "capsfilter"
+#define VIDEOCONVERT_SINK_PAD "videoconvert_sink_pad"
+#define VIDEOCONVERT "videoconvert"
+#define VIDEORATE "videorate"
+#define QUEUE "queue"
+#define VIDEOSCALE "videoscale"
+#define INPUT "input"
+#define REMOVING "removing"
+#define EOS_MANAGED "eos_managed"
+#define PROBE_ID "probe_id"
+#define LINK_PROBE_ID "link_probe_id"

 static GstStaticPadTemplate audio_sink_factory =
 GST_STATIC_PAD_TEMPLATE (AUDIO_SINK_PAD_NAME_COMP,
@@ -93,22 +108,6 @@
   gint output_width, output_height;
 };

-typedef struct _KmsCompositeMixerPortData KmsCompositeMixerPortData;
-
-struct _KmsCompositeMixerPortData
-{
-  KmsCompositeMixer *mixer;
-  gint id;
-  GstElement *videoconvert;
-  GstElement *capsfilter;
-  GstElement *videoscale;
-  GstElement *videorate;
-  GstElement *queue;
-  GstPad *video_mixer_pad, *videoconvert_sink_pad;
-  gboolean input;
-  gint probe_id, link_probe_id;
-};
-
 /* class initialization */

 G_DEFINE_TYPE_WITH_CODE (KmsCompositeMixer, kms_composite_mixer,
@@ -119,10 +118,14 @@
 static gint
 compare_port_data (gconstpointer a, gconstpointer b)
 {
-  KmsCompositeMixerPortData *port_data_a = (KmsCompositeMixerPortData *) a;
-  KmsCompositeMixerPortData *port_data_b = (KmsCompositeMixerPortData *) b;
-
-  return port_data_a->id - port_data_b->id;
+  KmsGenericStructure *port_data_a = KMS_GENERIC_STRUCTURE (a);
+  KmsGenericStructure *port_data_b = KMS_GENERIC_STRUCTURE (b);
+  gint id1, id2;
+
+  id1 = GPOINTER_TO_INT (kms_generic_structure_get (port_data_a, ID));
+  id2 = GPOINTER_TO_INT (kms_generic_structure_get (port_data_b, ID));
+
+  return id1 - id2;
 }

 static void
@@ -138,9 +141,9 @@
   values = g_list_sort (values, compare_port_data);

   for (l = values; l != NULL; l = l->next) {
-    KmsCompositeMixerPortData *port_data =
-        (KmsCompositeMixerPortData *) l->data;
-    if (port_data->input == FALSE) {
+    KmsGenericStructure *port_data = KMS_GENERIC_STRUCTURE (l->data);
+
+    if (GPOINTER_TO_INT (kms_generic_structure_get (port_data, INPUT)) == FALSE) {
       continue;
     }

@@ -161,17 +164,20 @@
         gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "AYUV",
         "width", G_TYPE_INT, width, "height", G_TYPE_INT, height,
         "framerate", GST_TYPE_FRACTION, 15, 1, NULL);
-    g_object_set (G_OBJECT (port_data->capsfilter), "caps", filtercaps, NULL);
+    g_object_set (G_OBJECT (kms_generic_structure_get (port_data,
+                CAPSFILTER)), "caps", filtercaps, NULL);
     gst_caps_unref (filtercaps);

     top = ((counter / N_ELEMENTS_WIDTH) * height);
     left = ((counter % N_ELEMENTS_WIDTH) * width);

-    g_object_set (port_data->video_mixer_pad, "xpos", left, "ypos", top,
-        "alpha", 1.0, NULL);
+    g_object_set (G_OBJECT (kms_generic_structure_get (port_data,
+                VIDEO_MIXER_PAD)), "xpos", left, "ypos", top, "alpha", 1.0,
+        NULL);
     counter++;

-    GST_DEBUG ("counter %d id_port %d ", counter, port_data->id);
+    GST_DEBUG ("counter %d id_port %d ", counter,
+        GPOINTER_TO_INT (kms_generic_structure_get (port_data, ID)));
     GST_DEBUG ("top %d left %d width %d height %d", top, left, width, height);
   }
   g_list_free (values);
@@ -180,73 +186,93 @@
 static gboolean
 remove_elements_from_pipeline (gpointer data)
 {
-  KmsCompositeMixerPortData *port_data = (KmsCompositeMixerPortData *) data;
-  KmsCompositeMixer *self = port_data->mixer;
+  KmsGenericStructure *port_data = KMS_GENERIC_STRUCTURE (data);
+  KmsCompositeMixer *self =
+      KMS_COMPOSITE_MIXER ((kms_generic_structure_get (port_data, MIXER)));
+  GstElement *videoconvert, *videoscale, *videorate, *capsfilter, *queue;
+  GstPad *video_mixer_pad, *videoconvert_sink_pad;
+  gint id;

   KMS_COMPOSITE_MIXER_LOCK (self);

-  gst_element_unlink (port_data->capsfilter,
-      port_data->mixer->priv->videomixer);
-
-  if (port_data->video_mixer_pad != NULL) {
-    gst_element_release_request_pad (self->priv->videomixer,
-        port_data->video_mixer_pad);
-    g_object_unref (port_data->video_mixer_pad);
-    port_data->video_mixer_pad = NULL;
-  }
-
-  g_object_ref (port_data->videoconvert);
-  g_object_ref (port_data->videorate);
-  g_object_ref (port_data->queue);
-  g_object_ref (port_data->videoscale);
-  g_object_ref (port_data->capsfilter);
-
-  gst_bin_remove_many (GST_BIN (self),
-      port_data->videoconvert, port_data->videoscale, port_data->capsfilter,
-      port_data->videorate, port_data->queue, NULL);
-
-  kms_base_hub_unlink_video_src (KMS_BASE_HUB (self), port_data->id);
+  capsfilter = kms_generic_structure_get (port_data, CAPSFILTER);
+  gst_element_unlink (capsfilter, self->priv->videomixer);
+
+  video_mixer_pad = kms_generic_structure_get (port_data, VIDEO_MIXER_PAD);
+  if (video_mixer_pad != NULL) {
+    gst_element_release_request_pad (self->priv->videomixer, video_mixer_pad);
+    g_object_unref (video_mixer_pad);
+    kms_generic_structure_set (port_data, VIDEO_MIXER_PAD, NULL);
+  }
+
+  videoconvert =
+      g_object_ref (kms_generic_structure_get (port_data, VIDEOCONVERT));
+  videorate = g_object_ref (kms_generic_structure_get (port_data, VIDEORATE));
+  queue = g_object_ref (kms_generic_structure_get (port_data, QUEUE));
+  videoscale = g_object_ref (kms_generic_structure_get (port_data, VIDEOSCALE));
+  g_object_ref (capsfilter);
+
+  videoconvert_sink_pad =
+      kms_generic_structure_get (port_data, VIDEOCONVERT_SINK_PAD);
+  g_object_unref (videoconvert_sink_pad);
+
+  kms_generic_structure_set (port_data, VIDEOCONVERT_SINK_PAD, NULL);
+  kms_generic_structure_set (port_data, VIDEOCONVERT, NULL);
+  kms_generic_structure_set (port_data, VIDEORATE, NULL);
+  kms_generic_structure_set (port_data, QUEUE, NULL);
+  kms_generic_structure_set (port_data, VIDEOSCALE, NULL);
+  kms_generic_structure_set (port_data, CAPSFILTER, NULL);
+
+  gst_bin_remove_many (GST_BIN (self), videoconvert, videoscale, capsfilter,
+      videorate, queue, NULL);
+
+  id = GPOINTER_TO_INT (kms_generic_structure_get (port_data, ID));
+  kms_base_hub_unlink_video_src (KMS_BASE_HUB (self), id);

   KMS_COMPOSITE_MIXER_UNLOCK (self);

-  gst_element_set_state (port_data->videoconvert, GST_STATE_NULL);
-  gst_element_set_state (port_data->videoscale, GST_STATE_NULL);
-  gst_element_set_state (port_data->videorate, GST_STATE_NULL);
-  gst_element_set_state (port_data->capsfilter, GST_STATE_NULL);
-  gst_element_set_state (port_data->queue, GST_STATE_NULL);
-
-  g_clear_object (&port_data->videoconvert_sink_pad);
-  g_clear_object (&port_data->videoconvert);
-  g_clear_object (&port_data->videoscale);
-  g_clear_object (&port_data->videorate);
-  g_clear_object (&port_data->capsfilter);
-  g_clear_object (&port_data->queue);
+  gst_element_set_state (videoconvert, GST_STATE_NULL);
+  gst_element_set_state (videoscale, GST_STATE_NULL);
+  gst_element_set_state (videorate, GST_STATE_NULL);
+  gst_element_set_state (capsfilter, GST_STATE_NULL);
+  gst_element_set_state (queue, GST_STATE_NULL);
+
+  g_object_unref (videoconvert);
+  g_object_unref (videoscale);
+  g_object_unref (videorate);
+  g_object_unref (capsfilter);
+  g_object_unref (queue);

   return G_SOURCE_REMOVE;
-}
-
-static void
-destroy_port_data (gpointer data)
-{
-  g_slice_free (KmsCompositeMixerPortData, data);
 }

 static GstPadProbeReturn
 cb_EOS_received (GstPad * pad, GstPadProbeInfo * info, gpointer data)
 {
-  KmsCompositeMixerPortData *port_data = (KmsCompositeMixerPortData *) data;
-  KmsCompositeMixer *self = port_data->mixer;
+  KmsGenericStructure *port_data = KMS_GENERIC_STRUCTURE (data);
+  KmsCompositeMixer *self =
+      KMS_COMPOSITE_MIXER (kms_generic_structure_get (port_data, MIXER));
   GstEvent *event;
+  gboolean removing;
+  gint probe_id;

   if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_EVENT (info)) != GST_EVENT_EOS) {
-    return GST_PAD_PROBE_PASS;
+    return GST_PAD_PROBE_OK;
   }

   KMS_COMPOSITE_MIXER_LOCK (self);

-  if (port_data->probe_id > 0) {
-    gst_pad_remove_probe (pad, port_data->probe_id);
-    port_data->probe_id = 0;
+  removing = GPOINTER_TO_INT (kms_generic_structure_get (port_data, REMOVING));
+  if (!removing) {
+    kms_generic_structure_set (port_data, EOS_MANAGED, GINT_TO_POINTER (TRUE));
+    KMS_COMPOSITE_MIXER_UNLOCK (self);
+    return GST_PAD_PROBE_OK;
+  }
+
+  probe_id = GPOINTER_TO_INT (kms_generic_structure_get (port_data, PROBE_ID));
+  if (probe_id > 0) {
+    gst_pad_remove_probe (pad, probe_id);
+    kms_generic_structure_set (port_data, PROBE_ID, GINT_TO_POINTER (0));
   }

   KMS_COMPOSITE_MIXER_UNLOCK (self);
@@ -255,7 +281,8 @@
   gst_pad_send_event (pad, event);

   kms_loop_idle_add_full (self->priv->loop, G_PRIORITY_DEFAULT,
-      remove_elements_from_pipeline, data, destroy_port_data);
+      remove_elements_from_pipeline, kms_generic_structure_ref (data),
+      (GDestroyNotify) kms_generic_structure_unref);

   return GST_PAD_PROBE_OK;
 }
@@ -263,41 +290,51 @@
 static void
 kms_composite_mixer_port_data_destroy (gpointer data)
 {
-  KmsCompositeMixerPortData *port_data = (KmsCompositeMixerPortData *) data;
-  KmsCompositeMixer *self = port_data->mixer;
+  KmsGenericStructure *port_data = KMS_GENERIC_STRUCTURE (data);
+  KmsCompositeMixer *self =
+      KMS_COMPOSITE_MIXER (kms_generic_structure_get (port_data, MIXER));
   GstPad *audiosink;
   gchar *padname;
-
-  if (!KMS_IS_COMPOSITE_MIXER (self)) {
-    destroy_port_data (port_data);
-    return;
-  }
+  gboolean input;
+  gint id;

   KMS_COMPOSITE_MIXER_LOCK (self);

-  kms_base_hub_unlink_video_sink (KMS_BASE_HUB (self), port_data->id);
-  kms_base_hub_unlink_audio_sink (KMS_BASE_HUB (self), port_data->id);
-
-  KMS_COMPOSITE_MIXER_UNLOCK (self);
-
-  if (port_data->input) {
+  kms_generic_structure_set (port_data, REMOVING, GINT_TO_POINTER (TRUE));
+  id = GPOINTER_TO_INT (kms_generic_structure_get (port_data, ID));
+
+  kms_base_hub_unlink_video_sink (KMS_BASE_HUB (self), id);
+  kms_base_hub_unlink_audio_sink (KMS_BASE_HUB (self), id);
+
+  input = GPOINTER_TO_INT (kms_generic_structure_get (port_data, INPUT));
+  if (input) {
     GstEvent *event;
     gboolean result;
     GstPad *pad;
-
-    pad = gst_element_get_static_pad (port_data->videorate, "sink");
-
-    if (pad == NULL)
+    GstElement *videoconvert, *videorate;
+
+    videorate = kms_generic_structure_get (port_data, VIDEORATE);
+    videoconvert = kms_generic_structure_get (port_data, VIDEOCONVERT);
+
+    if (videorate == NULL) {
+      KMS_COMPOSITE_MIXER_UNLOCK (self);
       return;
+    }
+
+    pad = gst_element_get_static_pad (videorate, "sink");
+
+    if (pad == NULL) {
+      KMS_COMPOSITE_MIXER_UNLOCK (self);
+      return;
+    }

     if (!GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLAG_EOS)) {

       event = gst_event_new_eos ();
       result = gst_pad_send_event (pad, event);

-      KMS_COMPOSITE_MIXER_LOCK (self);
-      if (port_data->input && self->priv->n_elems > 0) {
-        port_data->input = FALSE;
+      if (input && self->priv->n_elems > 0) {
+        kms_generic_structure_set (port_data, INPUT, GINT_TO_POINTER (FALSE));
         self->priv->n_elems--;
         kms_composite_mixer_recalculate_sizes (self);
       }
@@ -307,23 +344,57 @@
         GST_WARNING ("EOS event did not send");
       }
     } else {
-      GST_WARNING ("EOS event already sent");
+      gboolean remove = FALSE;
+
+      /* EOS callback was triggered before we could remove the port data */
+      /* so we have to remove elements to avoid memory leaks. */
+      remove =
+          GPOINTER_TO_INT (kms_generic_structure_get (port_data, EOS_MANAGED));
+      KMS_COMPOSITE_MIXER_UNLOCK (self);
+
+      if (remove) {
+        /* Remove pipeline without helding the mutex */
+        kms_loop_idle_add_full (self->priv->loop, G_PRIORITY_DEFAULT,
+            remove_elements_from_pipeline,
+            kms_generic_structure_ref (data),
+            (GDestroyNotify) kms_generic_structure_unref);
+      }
     }
-    gst_element_unlink (port_data->videoconvert, port_data->videorate);
+    gst_element_unlink (videoconvert, videorate);
     g_object_unref (pad);
   } else {
-    if (port_data->probe_id > 0) {
-      gst_pad_remove_probe (port_data->video_mixer_pad, port_data->probe_id);
+    GstElement *videoconvert;
+    GstPad *video_mixer_pad, *videoconvert_sink_pad;
+    gint probe_id, link_probe_id;
+
+    videoconvert =
+        g_object_ref (kms_generic_structure_get (port_data, VIDEOCONVERT));
+    kms_generic_structure_set (port_data, VIDEOCONVERT, NULL);
+
+    probe_id =
+        GPOINTER_TO_INT (kms_generic_structure_get (port_data, PROBE_ID));
+    video_mixer_pad = kms_generic_structure_get (port_data, VIDEO_MIXER_PAD);
+
+    if (probe_id > 0) {
+      gst_pad_remove_probe (video_mixer_pad, probe_id);
     }
-    if (port_data->link_probe_id > 0) {
-      gst_pad_remove_probe (port_data->videoconvert_sink_pad,
-          port_data->link_probe_id);
+
+    link_probe_id =
+        GPOINTER_TO_INT (kms_generic_structure_get (port_data, LINK_PROBE_ID));
+    videoconvert_sink_pad =
+        kms_generic_structure_get (port_data, VIDEOCONVERT_SINK_PAD);
+
+    if (link_probe_id > 0) {
+      gst_pad_remove_probe (videoconvert_sink_pad, link_probe_id);
     }
-    g_object_ref (port_data->videoconvert);
-    gst_bin_remove (GST_BIN (self), port_data->videoconvert);
-  }
-
-  padname = g_strdup_printf (AUDIO_SINK_PAD, port_data->id);
+    KMS_COMPOSITE_MIXER_UNLOCK (self);
+
+    gst_bin_remove (GST_BIN (self), videoconvert);
+    gst_element_set_state (videoconvert, GST_STATE_NULL);
+    g_object_unref (videoconvert);
+  }
+
+  padname = g_strdup_printf (AUDIO_SINK_PAD, id);
   audiosink = gst_element_get_static_pad (self->priv->audiomixer, padname);
   gst_element_release_request_pad (self->priv->audiomixer, audiosink);
   gst_object_unref (audiosink);
@@ -334,104 +405,118 @@
 link_to_videomixer (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
 {
   GstPadTemplate *sink_pad_template;
-  KmsCompositeMixerPortData *data = user_data;
+  KmsGenericStructure *data = KMS_GENERIC_STRUCTURE (user_data);
+  KmsCompositeMixer *mixer;
+  GstElement *videoconvert, *videoscale, *capsfilter, *videorate, *queue;
+  GstPad *video_mixer_pad;
+  gint probe_id;

   if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_EVENT (info)) !=
       GST_EVENT_STREAM_START) {
     return GST_PAD_PROBE_PASS;
   }

-  GST_DEBUG ("stream start detected");
-  KMS_COMPOSITE_MIXER_LOCK (data->mixer);
-
-  data->link_probe_id = 0;
+  mixer = KMS_COMPOSITE_MIXER (kms_generic_structure_get (data, MIXER));
+  GST_DEBUG ("stream start detected %d",
+      GPOINTER_TO_INT (kms_generic_structure_get (data, ID)));
+  KMS_COMPOSITE_MIXER_LOCK (mixer);
+
+  kms_generic_structure_set (data, LINK_PROBE_ID, GINT_TO_POINTER (0));
   sink_pad_template =
-      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (data->mixer->
+      gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (mixer->
           priv->videomixer), "sink_%u");

-  if (data->mixer->priv->videotestsrc == NULL) {
+  if (G_UNLIKELY (sink_pad_template == NULL)) {
+    GST_ERROR_OBJECT (mixer, "Error taking a new pad from videomixer");
+    KMS_COMPOSITE_MIXER_UNLOCK (mixer);
+    return GST_PAD_PROBE_DROP;
+  }
+
+  if (mixer->priv->videotestsrc == NULL) {
     GstElement *capsfilter;
     GstCaps *filtercaps;
-
-    data->mixer->priv->videotestsrc =
-        gst_element_factory_make ("videotestsrc", NULL);
-    capsfilter = gst_element_factory_make ("capsfilter", NULL);
-
-    g_object_set (data->mixer->priv->videotestsrc, "is-live", TRUE, "pattern",
+    GstPad *pad;
+
+    mixer->priv->videotestsrc = gst_element_factory_make ("videotestsrc", NULL);
+    capsfilter = gst_element_factory_make (CAPSFILTER, NULL);
+
+    g_object_set (mixer->priv->videotestsrc, "is-live", TRUE, "pattern",
         /*black */ 2, NULL);

     filtercaps =
         gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "AYUV",
-        "width", G_TYPE_INT, data->mixer->priv->output_width,
-        "height", G_TYPE_INT, data->mixer->priv->output_height,
+        "width", G_TYPE_INT, mixer->priv->output_width,
+        "height", G_TYPE_INT, mixer->priv->output_height,
         "framerate", GST_TYPE_FRACTION, 15, 1, NULL);
     g_object_set (G_OBJECT (capsfilter), "caps", filtercaps, NULL);
     gst_caps_unref (filtercaps);

-    gst_bin_add_many (GST_BIN (data->mixer), data->mixer->priv->videotestsrc,
+    gst_bin_add_many (GST_BIN (mixer), mixer->priv->videotestsrc,
         capsfilter, NULL);

-    gst_element_link (data->mixer->priv->videotestsrc, capsfilter);
+    gst_element_link (mixer->priv->videotestsrc, capsfilter);
+
+    /*link capsfilter -> videomixer */
+    pad = gst_element_request_pad (mixer->priv->videomixer, sink_pad_template,
+        NULL, NULL);
+
+    gst_element_link_pads (capsfilter, NULL,
+        mixer->priv->videomixer, GST_OBJECT_NAME (pad));
+    g_object_set (pad, "xpos", 0, "ypos", 0, "alpha", 0.0, NULL);
+    g_object_unref (pad);
+
     gst_element_sync_state_with_parent (capsfilter);
-
-    /*link capsfilter -> videomixer */
-    if (sink_pad_template != NULL) {
-      GstPad *pad = gst_element_request_pad (data->mixer->priv->videomixer,
-          sink_pad_template, NULL, NULL);
-
-      gst_element_link_pads (capsfilter, NULL,
-          data->mixer->priv->videomixer, GST_OBJECT_NAME (pad));
-      g_object_set (pad, "xpos", 0, "ypos", 0, "alpha", 0.0, NULL);
-
-      g_object_unref (pad);
-    }
-
-    gst_element_sync_state_with_parent (data->mixer->priv->videotestsrc);
-  }
-
-  data->videoscale = gst_element_factory_make ("videoscale", NULL);
-  data->capsfilter = gst_element_factory_make ("capsfilter", NULL);
-  data->videorate = gst_element_factory_make ("videorate", NULL);
-  data->queue = gst_element_factory_make ("queue", NULL);
-  data->input = TRUE;
-
-  gst_bin_add_many (GST_BIN (data->mixer), data->queue, data->videorate,
-      data->videoscale, data->capsfilter, NULL);
-
-  gst_element_sync_state_with_parent (data->videoscale);
-  gst_element_sync_state_with_parent (data->capsfilter);
-  gst_element_sync_state_with_parent (data->videorate);
-  gst_element_sync_state_with_parent (data->queue);
-
-  g_object_set (data->videorate, "average-period", 200 * GST_MSECOND, NULL);
-  g_object_set (data->queue, "flush-on-eos", TRUE, "max-size-buffers", 60,
+    gst_element_sync_state_with_parent (mixer->priv->videotestsrc);
+  }
+
+  videoscale = gst_element_factory_make (VIDEOSCALE, NULL);
+  capsfilter = gst_element_factory_make (CAPSFILTER, NULL);
+  videorate = gst_element_factory_make (VIDEORATE, NULL);
+  queue = gst_element_factory_make (QUEUE, NULL);
+
+  kms_generic_structure_set (data, VIDEOSCALE, videoscale);
+  kms_generic_structure_set (data, CAPSFILTER, capsfilter);
+  kms_generic_structure_set (data, VIDEORATE, videorate);
+  kms_generic_structure_set (data, QUEUE, queue);
+  kms_generic_structure_set (data, INPUT, GINT_TO_POINTER (TRUE));
+
+  gst_bin_add_many (GST_BIN (mixer), queue, videorate, videoscale, capsfilter,
       NULL);

-  gst_element_link_many (data->videorate, data->queue, data->videoscale,
-      data->capsfilter, NULL);
+  g_object_set (videorate, "average-period", 200 * GST_MSECOND, NULL);
+  g_object_set (queue, "flush-on-eos", TRUE, "max-size-buffers", 60, NULL);
+
+  gst_element_link_many (videorate, queue, videoscale, capsfilter, NULL);

   /*link capsfilter -> videomixer */
-  if (sink_pad_template != NULL) {
-    data->video_mixer_pad =
-        gst_element_request_pad (data->mixer->priv->videomixer,
-        sink_pad_template, NULL, NULL);
-    gst_element_link_pads (data->capsfilter, NULL,
-        data->mixer->priv->videomixer, GST_OBJECT_NAME (data->video_mixer_pad));
-  } else {
-    GST_ERROR ("Error taking a new pad from videomixer");
-  }
-
-  gst_element_link (data->videoconvert, data->videorate);
-
-  data->probe_id = gst_pad_add_probe (data->video_mixer_pad,
+  video_mixer_pad =
+      gst_element_request_pad (mixer->priv->videomixer,
+      sink_pad_template, NULL, NULL);
+  kms_generic_structure_set (data, VIDEO_MIXER_PAD, video_mixer_pad);
+  gst_element_link_pads (capsfilter, NULL,
+      mixer->priv->videomixer, GST_OBJECT_NAME (video_mixer_pad));
+
+  videoconvert = kms_generic_structure_get (data, VIDEOCONVERT);
+  gst_element_link (videoconvert, videorate);
+
+  probe_id = gst_pad_add_probe (video_mixer_pad,
       GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
-      (GstPadProbeCallback) cb_EOS_received, data, NULL);
+      (GstPadProbeCallback) cb_EOS_received,
+      kms_generic_structure_ref (data),
+      (GDestroyNotify) kms_generic_structure_unref);
+
+  kms_generic_structure_set (data, PROBE_ID, GINT_TO_POINTER (probe_id));
+
+  gst_element_sync_state_with_parent (videoscale);
+  gst_element_sync_state_with_parent (capsfilter);
+  gst_element_sync_state_with_parent (videorate);
+  gst_element_sync_state_with_parent (queue);

   /*recalculate the output sizes */
-  data->mixer->priv->n_elems++;
-  kms_composite_mixer_recalculate_sizes (data->mixer);
-
-  KMS_COMPOSITE_MIXER_UNLOCK (data->mixer);
+  mixer->priv->n_elems++;
+  kms_composite_mixer_recalculate_sizes (mixer);
+
+  KMS_COMPOSITE_MIXER_UNLOCK (mixer);

   return GST_PAD_PROBE_REMOVE;
 }
@@ -468,37 +553,50 @@
       (kms_composite_mixer_parent_class))->unhandle_port (mixer, id);
 }

-static KmsCompositeMixerPortData *
+static KmsGenericStructure *
 kms_composite_mixer_port_data_create (KmsCompositeMixer * mixer, gint id)
 {
-  KmsCompositeMixerPortData *data = g_slice_new0 (KmsCompositeMixerPortData);
+  KmsGenericStructure *data;
+  GstElement *videoconvert;
+  GstPad *videoconvert_sink_pad;
+  gint link_probe_id;
   gchar *padname;

-  data->mixer = mixer;
-  data->videoconvert = gst_element_factory_make ("videoconvert", NULL);
-
-  data->id = id;
-  data->input = FALSE;
-
-  gst_bin_add_many (GST_BIN (mixer), data->videoconvert, NULL);
-
-  gst_element_sync_state_with_parent (data->videoconvert);
+  data = kms_generic_structure_new ();
+  kms_generic_structure_set (data, MIXER, mixer);
+  kms_generic_structure_set (data, ID, GINT_TO_POINTER (id));
+  kms_generic_structure_set (data, INPUT, GINT_TO_POINTER (FALSE));
+  kms_generic_structure_set (data, REMOVING, GINT_TO_POINTER (FALSE));
+  kms_generic_structure_set (data, EOS_MANAGED, GINT_TO_POINTER (FALSE));
+
+  videoconvert = gst_element_factory_make (VIDEOCONVERT, NULL);
+  kms_generic_structure_set (data, VIDEOCONVERT, videoconvert);
+
+  gst_bin_add_many (GST_BIN (mixer), videoconvert, NULL);
+
+  gst_element_sync_state_with_parent (videoconvert);

   /*link basemixer -> video_agnostic */
-  kms_base_hub_link_video_sink (KMS_BASE_HUB (mixer), id,
-      data->videoconvert, "sink", FALSE);
+  kms_base_hub_link_video_sink (KMS_BASE_HUB (mixer), id, videoconvert, "sink",
+      FALSE);

   padname = g_strdup_printf (AUDIO_SINK_PAD, id);
   kms_base_hub_link_audio_sink (KMS_BASE_HUB (mixer), id,
       mixer->priv->audiomixer, padname, FALSE);
   g_free (padname);

-  data->videoconvert_sink_pad =
-      gst_element_get_static_pad (data->videoconvert, "sink");
-
-  data->link_probe_id = gst_pad_add_probe (data->videoconvert_sink_pad,
+  videoconvert_sink_pad = gst_element_get_static_pad (videoconvert, "sink");
+  kms_generic_structure_set (data, VIDEOCONVERT_SINK_PAD,
+      videoconvert_sink_pad);
+
+  link_probe_id = gst_pad_add_probe (videoconvert_sink_pad,
       GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_BLOCK,
-      (GstPadProbeCallback) link_to_videomixer, data, NULL);
+      (GstPadProbeCallback) link_to_videomixer,
+      kms_generic_structure_ref (data),
+      (GDestroyNotify) kms_generic_structure_unref);
+
+  kms_generic_structure_set (data, LINK_PROBE_ID,
+      GINT_TO_POINTER (link_probe_id));

   return data;
 }
@@ -552,7 +650,7 @@
     GstElement * mixer_end_point)
 {
   KmsCompositeMixer *self = KMS_COMPOSITE_MIXER (mixer);
-  KmsCompositeMixerPortData *port_data;
+  KmsGenericStructure *port_data;
   gint port_id;

   port_id = KMS_BASE_HUB_CLASS (G_OBJECT_CLASS
@@ -567,7 +665,7 @@
   if (self->priv->videomixer == NULL) {
     GstElement *videorate_mixer;

-    videorate_mixer = gst_element_factory_make ("videorate", NULL);
+    videorate_mixer = gst_element_factory_make (VIDEORATE, NULL);
     self->priv->videomixer = gst_element_factory_make ("compositor", NULL);
     g_object_set (G_OBJECT (self->priv->videomixer), "background", 1, NULL);
     self->priv->mixer_video_agnostic =


playerendpoint: use g_object_set|get|steal_qdata

Change-Id: I92eb87aa8295b37bcee72559de16bc47d54101de

--- src/gst-plugins/kmsplayerendpoint.c
+++ src/gst-plugins/kmsplayerendpoint.c
@@ -33,9 +33,14 @@
 #define URIDECODEBIN "uridecodebin"
 #define RTSPSRC "rtspsrc"

-#define APPSRC_DATA "appsrc_data"
-#define APPSINK_DATA "appsink_data"
-#define PTS_DATA "pts_data"
+#define APPSRC_KEY "appsrc-key"
+G_DEFINE_QUARK (APPSRC_KEY, appsrc);
+
+#define APPSINK_KEY "appsink-key"
+G_DEFINE_QUARK (APPSINK_KEY, appsink);
+
+#define PTS_KEY "pts-key"
+G_DEFINE_QUARK (PTS_KEY, pts);

 #define NETWORK_CACHE_DEFAULT 2000
 #define IS_PREROLL TRUE
@@ -445,7 +450,8 @@
   buffer = gst_buffer_make_writable (buffer);
   pts_orig = GST_BUFFER_PTS (buffer);

-  pts_data = (KmsPtsData *) g_object_get_data (G_OBJECT (appsink), PTS_DATA);
+  pts_data =
+      (KmsPtsData *) g_object_get_qdata (G_OBJECT (appsink), pts_quark ());

   if (is_preroll) {
     GST_DEBUG_OBJECT (appsink, "Preroll: reset base time");
@@ -800,11 +806,11 @@
     g_signal_connect (appsink, "new-preroll", G_CALLBACK (new_preroll_cb),
         appsrc);

-    g_object_set_data_full (G_OBJECT (appsink), PTS_DATA, kms_pts_data_new (),
-        kms_pts_data_destroy);
-
-    g_object_set_data (G_OBJECT (pad), APPSINK_DATA, appsink);
-    g_object_set_data (G_OBJECT (pad), APPSRC_DATA, appsrc);
+    g_object_set_qdata_full (G_OBJECT (appsink), pts_quark (),
+        kms_pts_data_new (), kms_pts_data_destroy);
+
+    g_object_set_qdata (G_OBJECT (pad), appsink_quark (), appsink);
+    g_object_set_qdata (G_OBJECT (pad), appsrc_quark (), appsrc);
   } else {
     GST_WARNING_OBJECT (self, "No supported pad: %" GST_PTR_FORMAT
         ". Connecting it to a fakesink", pad);
@@ -858,8 +864,8 @@

   kms_player_end_point_remove_stat_probe (self, pad);

-  appsink = g_object_steal_data (G_OBJECT (pad), APPSINK_DATA);
-  appsrc = g_object_steal_data (G_OBJECT (pad), APPSRC_DATA);
+  appsink = g_object_steal_qdata (G_OBJECT (pad), appsink_quark ());
+  appsrc = g_object_steal_qdata (G_OBJECT (pad), appsrc_quark ());

   if (appsink != NULL) {
     kms_remove_element_from_bin (GST_BIN (self->priv->pipeline), appsink);


egl/x11: cleanup init code

egl/x11: cleanup init code

No functional change, just rewriting it in an easier-to-understand way.

Signed-off-by: Eric Engestrom <96f164ad4d9b2b0dacf8ebee2bb1eeb3aa69adf1@engestrom.ch>
Reviewed-by: Emil Velikov <f20878473f414da183da19ee25c8722cc1d711e4@collabora.com>

--- src/egl/drivers/dri2/platform_x11.c
+++ src/egl/drivers/dri2/platform_x11.c
@@ -1467,24 +1467,20 @@
 EGLBoolean
 dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
 {
-   EGLBoolean initialized = EGL_TRUE;
-
-   int x11_dri2_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
-
-   if (x11_dri2_accel) {
+   EGLBoolean initialized = EGL_FALSE;
+
+   if (!getenv("LIBGL_ALWAYS_SOFTWARE")) {
 #ifdef HAVE_DRI3
-      if (getenv("LIBGL_DRI3_DISABLE") != NULL ||
-          !dri2_initialize_x11_dri3(drv, disp)) {
+      if (!getenv("LIBGL_DRI3_DISABLE"))
+         initialized = dri2_initialize_x11_dri3(drv, disp);
 #endif
-         if (!dri2_initialize_x11_dri2(drv, disp)) {
-            initialized = dri2_initialize_x11_swrast(drv, disp);
-         }
-#ifdef HAVE_DRI3
-      }
-#endif
-   } else {
+
+      if (!initialized)
+         initialized = dri2_initialize_x11_dri2(drv, disp);
+   }
+
+   if (!initialized)
       initialized = dri2_initialize_x11_swrast(drv, disp);
-   }

    return initialized;
 }


Minor update

Minor update

--- designs/rtl/sigma/sw/apps/crc32/crc32_main.c
+++ designs/rtl/sigma/sw/apps/crc32/crc32_main.c
@@ -5,6 +5,7 @@
 int main(int argc, char* argv[])
 {

+    IO_LED = 0x55aa55aa;
     IO_LED = crc32(INPUT, LEN);

     while (1) {}


comment

comment

--- pfl/pool.c
+++ pfl/pool.c
@@ -564,7 +564,12 @@
 	void *p;

 	POOL_LOCK(m);
-	/* (gdb) p m.ppm_u.ppmu_explist.pexl_pll */
+	/*
+	 * (gdb) p m.ppm_u.ppmu_explist.pexl_pll.
+	 *
+	 * Can we grow even if PPGF_NONBLOCK is set?
+	 *
+	 */
 	p = POOL_TRYGETOBJ(m);
 	if (p || (flags & PPGF_NONBLOCK))
 		PFL_GOTOERR(gotitem, 0);


fix bad allocated memory handling that was causing crash in pgsqllibinit() when realpath() returns NULL

--- pgsqllib.c
+++ pgsqllib.c
@@ -46,22 +46,18 @@

    char * prg;
    char * nprg;
-   char * dirtmp;

    prg = bstrdup ( argv[0] );
    nprg = basename ( prg );
    program_name = bstrdup ( nprg );
    FREE ( prg );

-   dirtmp = MALLOC ( PATH_MAX );
-   if ( realpath ( argv[0], dirtmp ) == NULL ){
+   program_directory = MALLOC ( PATH_MAX );
+   if ( realpath ( argv[0], program_directory ) == NULL ){
       /* error in resolving path */
-      FREE ( dirtmp );
-      dirtmp = argv[0];
-   }
-   program_directory = bstrdup ( dirtmp );
-
-   FREE ( dirtmp );
+      FREE ( program_directory );
+      program_directory = argv[0];
+   }
 }

 /* returns a pointer into program name variable */


Reduce names shown in tracker-status to not show org.freedesktop...

--- src/tracker-utils/tracker-status.c
+++ src/tracker-utils/tracker-status.c
@@ -505,7 +505,16 @@
 	g_print ("%s:\n", _("Miners"));

 	for (l = miners_available; l; l = l->next) {
+		const gchar *name;
 		gboolean is_running;
+
+		if (!strstr (l->data, TRACKER_MINER_DBUS_NAME_PREFIX)) {
+			g_critical ("We have a miner without the dbus name prefix? '%s'",
+				    (gchar*) l->data);
+			continue;
+		}
+
+		name = (gchar*) l->data + strlen (TRACKER_MINER_DBUS_NAME_PREFIX);

 		is_running = tracker_string_in_gslist (l->data, miners_running);

@@ -522,7 +531,7 @@
 				 is_paused ? "P" : "R",
 				 _("Progress"),
 				 progress * 100,
-				 (gchar*) l->data,
+				 name,
 				 _("Status"),
 				 status ? status : _("Unknown"));

@@ -531,7 +540,7 @@
 			g_print ("  [ ] %s: %3.0f%%, %s\n",
 				 _("Progress"),
 				 0.0,
-				 (gchar*) l->data);
+				 name);
 		}
 	}

@@ -546,6 +555,7 @@

 	g_print ("Press Ctrl+C to end follow of Tracker state\n");

+#if 0
 	proxy = client->proxy_statistics;

 	/* Set signal handlers */
@@ -608,6 +618,7 @@
 	/* 			     G_CALLBACK (index_service_stats_updated), */
 	/* 			     NULL, */
 	/* 			     NULL); */
+#endif

 	initialize_signal_handler ();


tracker-status: Improve output of command

--- src/tracker-utils/tracker-status.c
+++ src/tracker-utils/tracker-status.c
@@ -51,16 +51,17 @@
 static GHashTable *miners_progress;
 static GHashTable *miners_status;
 static gint longest_miner_name_length = 0;
-
-static gboolean   list_miners_running;
-static gboolean   list_miners_available;
-static gboolean   pause_details;
-static gchar     *miner_name;
-static gchar     *pause_reason;
-static gint       resume_cookie = -1;
-static gboolean   follow;
-static gboolean   detailed;
-static gboolean   print_version;
+static gint paused_length = 0;
+
+static gboolean list_miners_running;
+static gboolean list_miners_available;
+static gboolean pause_details;
+static gchar *miner_name;
+static gchar *pause_reason;
+static gint resume_cookie = -1;
+static gboolean follow;
+static gboolean detailed;
+static gboolean print_version;

 static GOptionEntry entries[] = {
 	{ "follow", 'f', 0, G_OPTION_ARG_NONE, &follow,
@@ -230,6 +231,7 @@
 	gchar time_str[64];
 	size_t len;
 	struct tm *local_time;
+	gchar *progress_str;

 	if (detailed) {
 		now = time ((time_t *) NULL);
@@ -245,31 +247,42 @@

 	name = tracker_miner_manager_get_display_name (manager, miner_name);

+	if (!is_running) {
+		progress_str = g_strdup_printf ("✗   ");
+	} else if (progress > 0.0 && progress < 1.0) {
+		progress_str = g_strdup_printf ("%-3.0f%%", progress * 100);
+	} else {
+		progress_str = g_strdup_printf ("✓   ");
+	}
+
 	if (is_running) {
-		const gchar *paused;
-		gint paused_len;
-
-		paused = _("PAUSED");
-		paused_len = strlen (paused);
-
-		g_print ("%s  %3.0f%%  %-*.*s %s%-*.*s%s %s %s\n",
+		g_print ("%s  %s  %-*.*s %s%-*.*s%s %s %s\n",
 		         time_str,
-		         progress * 100,
+		         progress_str,
 		         longest_miner_name_length,
 		         longest_miner_name_length,
 		         name,
 		         is_paused ? "(" : " ",
-		         paused_len,
-		         paused_len,
-		         is_paused ? paused : " ",
+		         paused_length,
+		         paused_length,
+		         is_paused ? _("PAUSED") : " ",
 		         is_paused ? ")" : " ",
 		         status ? "-" : "",
 		         status ? status : "");
 	} else {
-		g_print ("%s  ---   %s\n",
+		g_print ("%s  %s  %-*.*s  %-*.*s  - %s\n",
 		         time_str,
-		         name);
-	}
+		         progress_str,
+		         longest_miner_name_length,
+		         longest_miner_name_length,
+		         name,
+		         paused_length,
+		         paused_length,
+		         " ",
+		         _("Not running or is a disabled plugin"));
+	}
+
+	g_free (progress_str);
 }

 static void
@@ -279,18 +292,19 @@
 	gdouble progress;
 	gchar *status;
 	gchar time_str[64];
+	gchar *progress_str;

 	org_freedesktop_Tracker1_Status_get_progress (proxy, &progress, &error);

 	if (error) {
-		g_critical ("Couldn't retrieve tracker-store progress: %s\n", error->message);
+		g_critical ("Could not retrieve tracker-store progress: %s", error->message);
 		return;
 	}

 	org_freedesktop_Tracker1_Status_get_status (proxy, &status, &error);

 	if (error) {
-		g_critical ("Couldn't retrieve tracker-store status: %s\n", error->message);
+		g_critical ("Could not retrieve tracker-store status: %s", error->message);
 		return;
 	}

@@ -310,10 +324,19 @@
 		time_str[0] = '\0';
 	}

-	g_print ("%s: %s  %3.0f%%  %s\n",
-	         _("Store"),
+	if (progress > 0.0 && progress < 1.0) {
+		progress_str = g_strdup_printf ("%-3.0f%%", progress * 100);
+	} else {
+		progress_str = g_strdup_printf ("✓   ");
+	}
+
+	g_print ("%s  %s  %-*.*s    %s %s\n",
 	         time_str,
-	         progress * 100,
+	         progress_str,
+	         longest_miner_name_length + paused_length,
+	         longest_miner_name_length + paused_length,
+	         _("Journal replay"),
+	         status ? "-" : "",
 	         status ? status : "");
 }

@@ -628,7 +651,8 @@
 		return EXIT_SUCCESS;
 	}

-	g_print ("%s:\n", _("Miners"));
+	/* Work out lengths for output spacing */
+	paused_length = strlen (_("PAUSED"));

 	for (l = miners_available; l; l = l->next) {
 		const gchar *name;
@@ -636,6 +660,15 @@
 		name = tracker_miner_manager_get_display_name (manager, l->data);
 		longest_miner_name_length = MAX (longest_miner_name_length, strlen (name));
 	}
+
+	/* Display states */
+	g_print ("%s:\n", _("Store"));
+	init_store_proxy ();
+	store_print_state ();
+
+	g_print ("\n");
+
+	g_print ("%s:\n", _("Miners"));

 	for (l = miners_available; l; l = l->next) {
 		const gchar *name;
@@ -677,9 +710,6 @@
 		}
 	}

-	init_store_proxy ();
-	store_print_state ();
-
 	g_slist_foreach (miners_available, (GFunc) g_free, NULL);
 	g_slist_free (miners_available);

@@ -689,6 +719,7 @@
 	if (!follow) {
 		/* Do nothing further */
 		g_object_unref (client);
+		g_print ("\n");
 		return EXIT_SUCCESS;
 	}


 ------- Comment #1 From Max Horn  2006-04-17 03:08  [reply] -------

Created an attachment (id=106) [edit]
Patch for src/joystick/win32/SDL_mmjoystick.c

I am not even a Windows user, so take the following with a grain of salt:

SDL_mmjoystick.c  has a function GetJoystickName which obtains the joystick
name by looking at the registry. The way it does that seems very fishy to me.
Namely, it uses the parameter "index" to construct a registry value name (BTW,
those variables used in the code are really badly named). The value of "index"
in turn equals the current value of "numdevs", as called from
SDL_SYS_JoystickInit.

I read through the MSDN docs at
<http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/dnarinput/html/msdn_extdirect.asp>,
and I believe the simple fix is to replace line 183 of said file
  SYS_JoystickName[numdevs] = GetJoystickName(numdevs, joycaps.szRegKey);
by the following:
  SYS_JoystickName[numdevs] = GetJoystickName(SYS_JoystickID[i],
joycaps.szRegKey);

However, that is only *hiding* the real issue. Problem is, the list of
joysticks as returned by windows may contains "gaps", and the code deals
incorrectly with that. Namely those gaps occur if joysticks are
removed/(re)added, as the reporter observed.

The attached patch fixes this and another (off-by-one) issue in the code. But
since I have no Windows machine, I can't even test-compile it, so use with
caution.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401706

--- src/joystick/win32/SDL_mmjoystick.c
+++ src/joystick/win32/SDL_mmjoystick.c
@@ -154,34 +154,26 @@
 	JOYCAPS	joycaps;
 	MMRESULT result;

+	/* Reset the joystick ID & name mapping tables */
+	for ( i = 0; i < MAX_JOYSTICKS; ++i ) {
+		SYS_JoystickID[i] = 0;
+		SYS_JoystickName[i] = NULL;
+	}
+
+	/* Loop over all potential joystick devices */
 	numdevs = 0;
 	maxdevs = joyGetNumDevs();
-
-	if ( maxdevs > MAX_JOYSTICKS ) {
-		maxdevs = MAX_JOYSTICKS;
-	}
-
-
-	for ( i = 0; i < MAX_JOYSTICKS; i++ ) {
-		SYS_JoystickID[i] = JOYSTICKID1 + i;
-		SYS_JoystickName[i] = NULL;
-	}
-
-
-	for ( i = 0; (i < maxdevs); ++i ) {
+	for ( i = JOYSTICKID1; i < maxdevs && numdevs < MAX_JOYSTICKS; ++i ) {

-		/* added 8/31/2001 By Vitaliy Mikitchenko */
 		joyinfo.dwSize = sizeof(joyinfo);
 		joyinfo.dwFlags = JOY_RETURNALL;
-		/* end addition */
-
 		result = joyGetPosEx(SYS_JoystickID[i], &joyinfo);
 		if ( result == JOYERR_NOERROR ) {
-			result = joyGetDevCaps(SYS_JoystickID[i], &joycaps, sizeof(joycaps));
+			result = joyGetDevCaps(i, &joycaps, sizeof(joycaps));
 			if ( result == JOYERR_NOERROR ) {
-				SYS_JoystickID[numdevs] = SYS_JoystickID[i];
+				SYS_JoystickID[numdevs] = i;
 				SYS_Joystick[numdevs] = joycaps;
-				SYS_JoystickName[numdevs] = GetJoystickName(numdevs, joycaps.szRegKey);
+				SYS_JoystickName[numdevs] = GetJoystickName(i, joycaps.szRegKey);
 				numdevs++;
 			}
 		}


Convert a large macro into actual code. (dm)

git-svn-id: 30a5f035a20f1bc647618dbad7eea2a951b61b7c@8227 91a5dbb7-01b9-0310-9b5f-b28072856b6e

--- Drivers/Braille/HandyTech/braille.c
+++ Drivers/Braille/HandyTech/braille.c
@@ -1498,19 +1498,28 @@
                       unsigned int cellIndex = bytes[0] - 1;
                       unsigned int dataIndex;

-#define PRESSURE(pressure) \
-  if ((pressure) > highestPressure) { \
-    highestPressure = (pressure); \
-    readingPosition = cellIndex; \
-  } \
-  cellIndex += 1;
                       for (dataIndex=1; dataIndex<length; dataIndex+=1) {
-                        unsigned char byte = bytes[dataIndex];
-
-                        PRESSURE(HIGH_NIBBLE(byte) >> 4);
-                        PRESSURE(LOW_NIBBLE(byte));
+                        const unsigned char byte = bytes[dataIndex];
+
+                        const unsigned char pressures[] = {
+                          HIGH_NIBBLE(byte) >> 4,
+                          LOW_NIBBLE(byte)
+                        };
+
+                        const unsigned int pressureCount = ARRAY_COUNT(pressures);
+                        unsigned int pressureIndex;
+
+                        for (pressureIndex=0; pressureIndex<pressureCount; pressureIndex+=1) {
+                          const unsigned char pressure = pressures[pressureIndex];
+
+                          if (pressure > highestPressure) {
+                            highestPressure = pressure;
+                            readingPosition = cellIndex;
+                          }
+
+                          cellIndex += 1;
+                        }
                       }
-#undef PRESSURE

                       if (readingPosition >= cellCount) readingPosition = BRL_MSK_ARG;
                     }


Use != instead of < to check for emptiness of iterator range (fixes Bug 664)

--- Eigen/src/SparseCore/SparseMatrix.h
+++ Eigen/src/SparseCore/SparseMatrix.h
@@ -941,7 +941,7 @@
   typedef typename SparseMatrixType::Scalar Scalar;
   SparseMatrix<Scalar,IsRowMajor?ColMajor:RowMajor> trMat(mat.rows(),mat.cols());

-  if(begin<end)
+  if(begin!=end)
   {
     // pass 1: count the nnz per inner-vector
     VectorXi wi(trMat.outerSize());


lib-http: Minor change to make sure http_response_header.size is always correct. The current http-header-parser already guaranteed that it is, but this change just adds extra guarantees that it won't break in future. Besides, this change improves the performance slightly by avoiding strlen().

--- src/lib-http/http-response-parser.c
+++ src/lib-http/http-response-parser.c
@@ -267,10 +267,12 @@
 {
 	struct http_response_header *hdr;
 	struct http_parser hparser;
+	void *value;

 	hdr = array_append_space(&parser->response->headers);
 	hdr->key = p_strdup(parser->response_pool, name);
-	hdr->value = p_strndup(parser->response_pool, data, size);
+	hdr->value = value = p_malloc(parser->response_pool, size+1);
+	memcpy(value, data, size);
 	hdr->size = size;

 	switch (name[0]) {


Function corrections in discrete boundary class

--- src/lib/boundary/DiscreteBoundary.h
+++ src/lib/boundary/DiscreteBoundary.h
@@ -89,13 +89,13 @@
 			 *
 			 *  \tparam Container vertices container
 			 */
-			template<template<typename> class Container>
-			void addVerticesString(const Container<mathtools::affine::Point<2> > &vertstr)
+			template<typename Container>
+			void addVerticesPoint(const Container &vertstr)
 			{
 				unsigned int ind = m_vecvert.size();
 				m_vecvert.resize(m_vecvert.size() + vertstr.size());
 				m_listind.push_back(std::list<unsigned int>());
-				for(typename Container<Eigen::Vector2d>::const_iterator it = vertstr.begin(); it != vertstr.end(); it++)
+				for(typename Container::const_iterator it = vertstr.begin(); it != vertstr.end(); it++)
 				{
 					m_vecvert[ind] = it->getCoords(m_frame);
 					m_listind.rbegin()->push_back(ind);
@@ -110,13 +110,13 @@
 			 *
 			 *  \tparam Container vertices container
 			 */
-			template<template<typename> class Container>
-			void addVerticesString(const Container<Eigen::Vector2d> &vertstr)
+			template<typename Container>
+			void addVerticesVector(const Container &vertstr)
 			{
 				unsigned int ind = m_vecvert.size();
 				m_vecvert.resize(m_vecvert.size() + vertstr.size());
 				m_listind.push_back(std::list<unsigned int>());
-				for(typename Container<Eigen::Vector2d>::const_iterator it = vertstr.begin(); it != vertstr.end(); it++)
+				for(typename Container::const_iterator it = vertstr.begin(); it != vertstr.end(); it++)
 				{
 					m_vecvert[ind] = *it;
 					m_listind.rbegin()->push_back(ind);


Fix a problem in the recently introduced TQtLock class.

git-svn-id: ecbadac9c76e8cf640a0bca86f6bd796c98521e3@12280 27541ba8-7e3a-0410-8455-c3a389f83636

--- qt/inc/TQtLock.h
+++ qt/inc/TQtLock.h
@@ -1,4 +1,4 @@
-// @(#)root/qt:$Name:  $:$Id: TQtLock.h,v 1.2 2005/07/08 00:26:35 fine Exp $
+// @(#)root/qt:$Name:  $:$Id: TQtLock.h,v 1.1 2005/07/08 06:43:09 brun Exp $
 // Author: Giulio Eulisse  04/07/2005
 #ifndef ROOT_TQtLock
 #define ROOT_TQtLock
@@ -18,14 +18,14 @@
 {
  public:
     TQtLock (void) { Lock();   }
-   ~TQtLock (void) { Unlock(); }
+   ~TQtLock (void) { UnLock(); }
     void Lock(Bool_t on=kTRUE) {
        if (qApp) {
           if (on)  qApp->lock();
           else     qApp->unlock();
        }
     }
-    void Unlock(Bool_t on=kFALSE) { Lock(!on); }
+    void UnLock(Bool_t on=kTRUE) { Lock(!on); }
 };

 #endif