[{"id":33616,"web_url":"https://patchwork.libcamera.org/comment/33616/","msgid":"<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>","date":"2025-03-17T18:54:09","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Barnabás\n\nOn Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n> Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n> for each control so that its existence can be checked easily\n> and without extra version checks.\n>\n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n\nDo we really want this ? Applications should discover controls\nprogrammatically.\n\nOr is this useful for ABI compliance validation ?\n\n> ---\n>  include/libcamera/control_ids.h.in | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> index 5d0594c68..8f037589d 100644\n> --- a/include/libcamera/control_ids.h.in\n> +++ b/include/libcamera/control_ids.h.in\n> @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n>  extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n>  {% endif -%}\n>  extern const Control<{{ctrl.type}}> {{ctrl.name}};\n> +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n>  {% endfor -%}\n>\n>  {% if vendor != 'libcamera' %}\n> --\n> 2.49.0\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id BA360C32FA\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 17 Mar 2025 18:54:15 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D42B06894C;\n\tMon, 17 Mar 2025 19:54:14 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1EAAB68826\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 17 Mar 2025 19:54:13 +0100 (CET)","from ideasonboard.com (93-61-96-190.ip145.fastwebnet.it\n\t[93.61.96.190])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 63A9D352;\n\tMon, 17 Mar 2025 19:52:31 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Nr/euLUf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742237551;\n\tbh=eVyOwmVoelKYLjtGUC1E75BLwHSRUbcU5vgVWnW6OwE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Nr/euLUfW0HW1Uc4g55Bdt8yg/KWPrByrxt0BX4F8Xc3VauJlfsVKUoyvsr++/SY4\n\tCIxgwtCyZ9NDlx2bgGkWwhoT25FPO2mg+4al26fdreRG4QfmeYgli0+p+WUc1IqxwT\n\tlzs8+8TTFX09ZEhozwR7sGjR+Q+a+BG3pVNzur8M=","Date":"Mon, 17 Mar 2025 19:54:09 +0100","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","Message-ID":"<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33619,"web_url":"https://patchwork.libcamera.org/comment/33619/","msgid":"<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>","date":"2025-03-17T21:00:20","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n\n2025. 03. 17. 19:54 keltezéssel, Jacopo Mondi írta:\n> Hi Barnabás\n> \n> On Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n>> Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n>> for each control so that its existence can be checked easily\n>> and without extra version checks.\n>>\n>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> \n> Do we really want this ?\n\nGood question, hence the RFC; I don't think there is a very nice\nway to discover (and use) controls at comptime/runtime. Also note\nthat the control namespaces already have their own existence macros\n(e.g. `LIBCAMERA_HAS_RPI_VENDOR_CONTROLS`).\n\n> Applications should discover controls\n> programmatically.\n\nWhat do you have in mind? Looking up the numeric id in the appropriate\n`ControlIdMap` by the (namespace, name) pair?\n\n\nRegards,\nBarnabás Pőcze\n\n\n> \n> Or is this useful for ABI compliance validation ?\n> \n>> ---\n>>   include/libcamera/control_ids.h.in | 1 +\n>>   1 file changed, 1 insertion(+)\n>>\n>> diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n>> index 5d0594c68..8f037589d 100644\n>> --- a/include/libcamera/control_ids.h.in\n>> +++ b/include/libcamera/control_ids.h.in\n>> @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n>>   extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n>>   {% endif -%}\n>>   extern const Control<{{ctrl.type}}> {{ctrl.name}};\n>> +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n>>   {% endfor -%}\n>>\n>>   {% if vendor != 'libcamera' %}\n>> --\n>> 2.49.0\n>>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0299BC32FA\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 17 Mar 2025 21:00:27 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4345E68826;\n\tMon, 17 Mar 2025 22:00:26 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 951CE617F8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 17 Mar 2025 22:00:24 +0100 (CET)","from [192.168.33.13] (185.221.143.221.nat.pool.zt.hu\n\t[185.221.143.221])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id CB2798DB;\n\tMon, 17 Mar 2025 21:58:42 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jCk9Xvaf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742245122;\n\tbh=mSi0Qic+LDg6APAwbW1ym6aLX3UKVyTAS1WtShL4nx0=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=jCk9XvafD7yL7/GIwzhZfuhLuud5WFfMShCSPtkKzIQGxhomIbWl3qcKKHmhra4OM\n\tSKEjKUIIGetvylv1lRA6Bb1s/Y5WNpUNl1fZ/C3eeeFvaiUrBd8JdvFnDJr1S2JJOG\n\tWH1gwrDSqpxnbmO1j10P6xvFVDtGphYydKQUNFjg=","Message-ID":"<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>","Date":"Mon, 17 Mar 2025 22:00:20 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>\n\t<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33628,"web_url":"https://patchwork.libcamera.org/comment/33628/","msgid":"<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>","date":"2025-03-18T08:11:27","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Barnabás\n\nOn Mon, Mar 17, 2025 at 10:00:20PM +0100, Barnabás Pőcze wrote:\n> Hi\n>\n>\n> 2025. 03. 17. 19:54 keltezéssel, Jacopo Mondi írta:\n> > Hi Barnabás\n> >\n> > On Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n> > > Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n> > > for each control so that its existence can be checked easily\n> > > and without extra version checks.\n> > >\n> > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> >\n> > Do we really want this ?\n>\n> Good question, hence the RFC; I don't think there is a very nice\n> way to discover (and use) controls at comptime/runtime. Also note\n\nWhat would the use case be ?\n\n> that the control namespaces already have their own existence macros\n> (e.g. `LIBCAMERA_HAS_RPI_VENDOR_CONTROLS`).\n\n>\n> > Applications should discover controls\n> > programmatically.\n>\n> What do you have in mind? Looking up the numeric id in the appropriate\n> `ControlIdMap` by the (namespace, name) pair?\n\nIf you mean Camera::controls() and Camera::properties() then yes, I\nthink applications should enumerate the supported controls from there\nand not rely on compile-time defines, as even if a control is defined\nit doesn't mean it is supported by the camera.\n\n>\n>\n> Regards,\n> Barnabás Pőcze\n>\n>\n> >\n> > Or is this useful for ABI compliance validation ?\n> >\n> > > ---\n> > >   include/libcamera/control_ids.h.in | 1 +\n> > >   1 file changed, 1 insertion(+)\n> > >\n> > > diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> > > index 5d0594c68..8f037589d 100644\n> > > --- a/include/libcamera/control_ids.h.in\n> > > +++ b/include/libcamera/control_ids.h.in\n> > > @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n> > >   extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n> > >   {% endif -%}\n> > >   extern const Control<{{ctrl.type}}> {{ctrl.name}};\n> > > +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n> > >   {% endfor -%}\n> > >\n> > >   {% if vendor != 'libcamera' %}\n> > > --\n> > > 2.49.0\n> > >\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 7E174BD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Mar 2025 08:11:33 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C0AA268947;\n\tTue, 18 Mar 2025 09:11:32 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 79ED3687FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Mar 2025 09:11:31 +0100 (CET)","from ideasonboard.com (93-61-96-190.ip145.fastwebnet.it\n\t[93.61.96.190])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4BB17A2F;\n\tTue, 18 Mar 2025 09:09:49 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"NaBhV3e4\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742285389;\n\tbh=OQj15EeBaBINRdrRhzDz7aLZUnDDWDbCJotsxH1ViHg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=NaBhV3e4TItdQtqT8OcvXaN+eGdTvswFaX55S1kStRPFK+fECW4gAbFkp80PvxLBq\n\t2cwqqW1FLiBaqasRWOurQUkuAj7dWpzFDB1oiCuSHP9IkUNcv9iKr1dAtoROC+ZW0M\n\tIGE/yRUvX42Mr4RcPoTVM7DV0Y0ZpeKvkKTqnmnI=","Date":"Tue, 18 Mar 2025 09:11:27 +0100","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","Message-ID":"<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>\n\t<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>\n\t<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33641,"web_url":"https://patchwork.libcamera.org/comment/33641/","msgid":"<20250318150015.GD10085@pendragon.ideasonboard.com>","date":"2025-03-18T15:00:15","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Tue, Mar 18, 2025 at 09:11:27AM +0100, Jacopo Mondi wrote:\n> On Mon, Mar 17, 2025 at 10:00:20PM +0100, Barnabás Pőcze wrote:\n> > 2025. 03. 17. 19:54 keltezéssel, Jacopo Mondi írta:\n> > > On Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n> > > > Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n> > > > for each control so that its existence can be checked easily\n> > > > and without extra version checks.\n> > > >\n> > > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> > >\n> > > Do we really want this ?\n> >\n> > Good question, hence the RFC; I don't think there is a very nice\n> > way to discover (and use) controls at comptime/runtime. Also note\n> \n> What would the use case be ?\n> \n> > that the control namespaces already have their own existence macros\n> > (e.g. `LIBCAMERA_HAS_RPI_VENDOR_CONTROLS`).\n> \n> >\n> > > Applications should discover controls\n> > > programmatically.\n> >\n> > What do you have in mind? Looking up the numeric id in the appropriate\n> > `ControlIdMap` by the (namespace, name) pair?\n> \n> If you mean Camera::controls() and Camera::properties() then yes, I\n> think applications should enumerate the supported controls from there\n> and not rely on compile-time defines, as even if a control is defined\n> it doesn't mean it is supported by the camera.\n\nTrue, but an application that would check if Camera::controls()\ncontains, for instance, controls::AE_ENABLE with\n\n\tif (camera->controls().count(controls::AE_ENABLE))\n\nwill not compile if the libcamera version it compiles against does not\ndefine the AeEnable control. Barnabás' patch allows fixing that with\nconditional compilation.\n\n> > > Or is this useful for ABI compliance validation ?\n> > >\n> > > > ---\n> > > >   include/libcamera/control_ids.h.in | 1 +\n> > > >   1 file changed, 1 insertion(+)\n> > > >\n> > > > diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> > > > index 5d0594c68..8f037589d 100644\n> > > > --- a/include/libcamera/control_ids.h.in\n> > > > +++ b/include/libcamera/control_ids.h.in\n> > > > @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n> > > >   extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n> > > >   {% endif -%}\n> > > >   extern const Control<{{ctrl.type}}> {{ctrl.name}};\n> > > > +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n> > > >   {% endfor -%}\n> > > >\n> > > >   {% if vendor != 'libcamera' %}","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id CCE60C32F5\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Mar 2025 15:00:41 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id F00CB68942;\n\tTue, 18 Mar 2025 16:00:40 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 61A1168940\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Mar 2025 16:00:39 +0100 (CET)","from pendragon.ideasonboard.com (85-76-135-144-nat.elisa-mobile.fi\n\t[85.76.135.144])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C21FAA2F;\n\tTue, 18 Mar 2025 15:58:56 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"PkLieHEq\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742309937;\n\tbh=3CaxsW/u+vHP7271wKlP+kLXtcJHC9WTrcKUjzomRj8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=PkLieHEqDdEwgxWf2NXaG4wriUAjela7IQgXmx8ypremUJ6KJTF6dzMwQLqkL2vm0\n\tu+bLLX4AOjnNrZz8ShwLgjBrhGtdIQdbtKqf5ph8XC+oaeXAuFT0sxWrg/kiDB4RfX\n\tt5c+2PBOTY0SylpUnCkUwYhPtnR5l7II8jhF6emg=","Date":"Tue, 18 Mar 2025 17:00:15 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","Message-ID":"<20250318150015.GD10085@pendragon.ideasonboard.com>","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>\n\t<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>\n\t<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>\n\t<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33643,"web_url":"https://patchwork.libcamera.org/comment/33643/","msgid":"<x7qmcry4m22r2euhvkvvkejbr3v6qto4krqbroxxhsl72e7prw@x5ivrqsajwii>","date":"2025-03-18T17:22:45","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Laurent\n\nOn Tue, Mar 18, 2025 at 05:00:15PM +0200, Laurent Pinchart wrote:\n> On Tue, Mar 18, 2025 at 09:11:27AM +0100, Jacopo Mondi wrote:\n> > On Mon, Mar 17, 2025 at 10:00:20PM +0100, Barnabás Pőcze wrote:\n> > > 2025. 03. 17. 19:54 keltezéssel, Jacopo Mondi írta:\n> > > > On Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n> > > > > Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n> > > > > for each control so that its existence can be checked easily\n> > > > > and without extra version checks.\n> > > > >\n> > > > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> > > >\n> > > > Do we really want this ?\n> > >\n> > > Good question, hence the RFC; I don't think there is a very nice\n> > > way to discover (and use) controls at comptime/runtime. Also note\n> >\n> > What would the use case be ?\n> >\n> > > that the control namespaces already have their own existence macros\n> > > (e.g. `LIBCAMERA_HAS_RPI_VENDOR_CONTROLS`).\n> >\n> > >\n> > > > Applications should discover controls\n> > > > programmatically.\n> > >\n> > > What do you have in mind? Looking up the numeric id in the appropriate\n> > > `ControlIdMap` by the (namespace, name) pair?\n> >\n> > If you mean Camera::controls() and Camera::properties() then yes, I\n> > think applications should enumerate the supported controls from there\n> > and not rely on compile-time defines, as even if a control is defined\n> > it doesn't mean it is supported by the camera.\n>\n> True, but an application that would check if Camera::controls()\n> contains, for instance, controls::AE_ENABLE with\n>\n> \tif (camera->controls().count(controls::AE_ENABLE))\n>\n> will not compile if the libcamera version it compiles against does not\n> define the AeEnable control. Barnabás' patch allows fixing that with\n> conditional compilation.\n\nDo we really want applications to #ifdef on controls ?? I thought\ncontrols are part of ABI, so once an application knows which version\nof libcamera it link against, the list of defined controls should be\nfixed. But yes, we don't have ABI stability, so...\n\nNot that I'm against this patch, just that seems to encourage bad code\npractices in applications.\n\n>\n> > > > Or is this useful for ABI compliance validation ?\n> > > >\n> > > > > ---\n> > > > >   include/libcamera/control_ids.h.in | 1 +\n> > > > >   1 file changed, 1 insertion(+)\n> > > > >\n> > > > > diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> > > > > index 5d0594c68..8f037589d 100644\n> > > > > --- a/include/libcamera/control_ids.h.in\n> > > > > +++ b/include/libcamera/control_ids.h.in\n> > > > > @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n> > > > >   extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n> > > > >   {% endif -%}\n> > > > >   extern const Control<{{ctrl.type}}> {{ctrl.name}};\n> > > > > +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n> > > > >   {% endfor -%}\n> > > > >\n> > > > >   {% if vendor != 'libcamera' %}\n>\n> --\n> Regards,\n>\n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 6FE03C32F5\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Mar 2025 17:22:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A4FD168947;\n\tTue, 18 Mar 2025 18:22:50 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0CE3668940\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Mar 2025 18:22:49 +0100 (CET)","from ideasonboard.com (93-61-96-190.ip145.fastwebnet.it\n\t[93.61.96.190])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8FE3B778;\n\tTue, 18 Mar 2025 18:21:06 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"KDdSWcHo\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742318466;\n\tbh=KKOFC/tk2takwXH7htOtT025Gvj720RxAFvwGogdH18=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=KDdSWcHo1K1U0VSIZR22TZL0t55K2X4eAZOy3blspYlorhjjt+/iL6474wbug6fSM\n\t/sRyJiH9r0lPjRL17xRc4BUgi5EuaOeM/YxxYF9s1ikRlq6nNxQyh1QaoLeThL5ESF\n\t1/9F5uqQsnTUXzioU1pupHOx6KUKEhs9c1dUCU0E=","Date":"Tue, 18 Mar 2025 18:22:45 +0100","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>, =?utf-8?b?QmFybmFiw6Fz?=\n\t=?utf-8?q?_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","Message-ID":"<x7qmcry4m22r2euhvkvvkejbr3v6qto4krqbroxxhsl72e7prw@x5ivrqsajwii>","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>\n\t<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>\n\t<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>\n\t<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>\n\t<20250318150015.GD10085@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20250318150015.GD10085@pendragon.ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33644,"web_url":"https://patchwork.libcamera.org/comment/33644/","msgid":"<20250318204357.GD22890@pendragon.ideasonboard.com>","date":"2025-03-18T20:43:57","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Tue, Mar 18, 2025 at 06:22:45PM +0100, Jacopo Mondi wrote:\n> On Tue, Mar 18, 2025 at 05:00:15PM +0200, Laurent Pinchart wrote:\n> > On Tue, Mar 18, 2025 at 09:11:27AM +0100, Jacopo Mondi wrote:\n> > > On Mon, Mar 17, 2025 at 10:00:20PM +0100, Barnabás Pőcze wrote:\n> > > > 2025. 03. 17. 19:54 keltezéssel, Jacopo Mondi írta:\n> > > > > On Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n> > > > > > Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n> > > > > > for each control so that its existence can be checked easily\n> > > > > > and without extra version checks.\n> > > > > >\n> > > > > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> > > > >\n> > > > > Do we really want this ?\n> > > >\n> > > > Good question, hence the RFC; I don't think there is a very nice\n> > > > way to discover (and use) controls at comptime/runtime. Also note\n> > >\n> > > What would the use case be ?\n> > >\n> > > > that the control namespaces already have their own existence macros\n> > > > (e.g. `LIBCAMERA_HAS_RPI_VENDOR_CONTROLS`).\n> > >\n> > > >\n> > > > > Applications should discover controls\n> > > > > programmatically.\n> > > >\n> > > > What do you have in mind? Looking up the numeric id in the appropriate\n> > > > `ControlIdMap` by the (namespace, name) pair?\n> > >\n> > > If you mean Camera::controls() and Camera::properties() then yes, I\n> > > think applications should enumerate the supported controls from there\n> > > and not rely on compile-time defines, as even if a control is defined\n> > > it doesn't mean it is supported by the camera.\n> >\n> > True, but an application that would check if Camera::controls()\n> > contains, for instance, controls::AE_ENABLE with\n> >\n> > \tif (camera->controls().count(controls::AE_ENABLE))\n> >\n> > will not compile if the libcamera version it compiles against does not\n> > define the AeEnable control. Barnabás' patch allows fixing that with\n> > conditional compilation.\n> \n> Do we really want applications to #ifdef on controls ?? I thought\n> controls are part of ABI, so once an application knows which version\n> of libcamera it link against, the list of defined controls should be\n> fixed. But yes, we don't have ABI stability, so...\n\nVersion checks are another option, I'm not against that.\n\n> Not that I'm against this patch, just that seems to encourage bad code\n> practices in applications.\n> \n> > > > > Or is this useful for ABI compliance validation ?\n> > > > >\n> > > > > > ---\n> > > > > >   include/libcamera/control_ids.h.in | 1 +\n> > > > > >   1 file changed, 1 insertion(+)\n> > > > > >\n> > > > > > diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> > > > > > index 5d0594c68..8f037589d 100644\n> > > > > > --- a/include/libcamera/control_ids.h.in\n> > > > > > +++ b/include/libcamera/control_ids.h.in\n> > > > > > @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n> > > > > >   extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n> > > > > >   {% endif -%}\n> > > > > >   extern const Control<{{ctrl.type}}> {{ctrl.name}};\n> > > > > > +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n> > > > > >   {% endfor -%}\n> > > > > >\n> > > > > >   {% if vendor != 'libcamera' %}","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 42D57C326C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Mar 2025 20:44:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 512C368942;\n\tTue, 18 Mar 2025 21:44:22 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A44436893F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Mar 2025 21:44:20 +0100 (CET)","from pendragon.ideasonboard.com (unknown [194.75.195.10])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id F2769778;\n\tTue, 18 Mar 2025 21:42:37 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"M1sW8A9M\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742330558;\n\tbh=WATvJs8ML+Eiid228GHomnsPurH87+Mvd1JkzK83NtQ=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=M1sW8A9MprpAF/034j5FgrpBOflZbe1VxXDFUUVrEqOp4fxWRl5N0/RUP05fWUj62\n\teeA36H38A9tPPO0v9gXZfC9PuhbdryOegBTjL9Hd69Db7RgP/gMhlWh33VADiD2zRg\n\tfmaZyruWqWDoXVNKxHPLt14+IJMXg9Rj0k9wTiJ4=","Date":"Tue, 18 Mar 2025 22:43:57 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","Message-ID":"<20250318204357.GD22890@pendragon.ideasonboard.com>","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>\n\t<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>\n\t<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>\n\t<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>\n\t<20250318150015.GD10085@pendragon.ideasonboard.com>\n\t<x7qmcry4m22r2euhvkvvkejbr3v6qto4krqbroxxhsl72e7prw@x5ivrqsajwii>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<x7qmcry4m22r2euhvkvvkejbr3v6qto4krqbroxxhsl72e7prw@x5ivrqsajwii>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33647,"web_url":"https://patchwork.libcamera.org/comment/33647/","msgid":"<174234091073.3286393.9194435253968802739@ping.linuxembedded.co.uk>","date":"2025-03-18T23:35:10","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Laurent Pinchart (2025-03-18 20:43:57)\n> On Tue, Mar 18, 2025 at 06:22:45PM +0100, Jacopo Mondi wrote:\n> > On Tue, Mar 18, 2025 at 05:00:15PM +0200, Laurent Pinchart wrote:\n> > > On Tue, Mar 18, 2025 at 09:11:27AM +0100, Jacopo Mondi wrote:\n> > > > On Mon, Mar 17, 2025 at 10:00:20PM +0100, Barnabás Pőcze wrote:\n> > > > > 2025. 03. 17. 19:54 keltezéssel, Jacopo Mondi írta:\n> > > > > > On Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n> > > > > > > Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n> > > > > > > for each control so that its existence can be checked easily\n> > > > > > > and without extra version checks.\n> > > > > > >\n> > > > > > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> > > > > >\n> > > > > > Do we really want this ?\n> > > > >\n> > > > > Good question, hence the RFC; I don't think there is a very nice\n> > > > > way to discover (and use) controls at comptime/runtime. Also note\n> > > >\n> > > > What would the use case be ?\n> > > >\n> > > > > that the control namespaces already have their own existence macros\n> > > > > (e.g. `LIBCAMERA_HAS_RPI_VENDOR_CONTROLS`).\n> > > >\n> > > > >\n> > > > > > Applications should discover controls\n> > > > > > programmatically.\n> > > > >\n> > > > > What do you have in mind? Looking up the numeric id in the appropriate\n> > > > > `ControlIdMap` by the (namespace, name) pair?\n> > > >\n> > > > If you mean Camera::controls() and Camera::properties() then yes, I\n> > > > think applications should enumerate the supported controls from there\n> > > > and not rely on compile-time defines, as even if a control is defined\n> > > > it doesn't mean it is supported by the camera.\n> > >\n> > > True, but an application that would check if Camera::controls()\n> > > contains, for instance, controls::AE_ENABLE with\n> > >\n> > >     if (camera->controls().count(controls::AE_ENABLE))\n> > >\n> > > will not compile if the libcamera version it compiles against does not\n> > > define the AeEnable control. Barnabás' patch allows fixing that with\n> > > conditional compilation.\n> > \n> > Do we really want applications to #ifdef on controls ?? I thought\n> > controls are part of ABI, so once an application knows which version\n> > of libcamera it link against, the list of defined controls should be\n> > fixed. But yes, we don't have ABI stability, so...\n> \n> Version checks are another option, I'm not against that.\n\nI think something like this would be helpful to some applications\nalready.. We might always think 'the latest libcamera' is the best to\nuse - but LTS distributions will still exist shipping libcamera 0.3 when\nwe reach later versions - and 'applications' will need a way to still be\nable to compile against the older versions where possible.\n\n\n> > Not that I'm against this patch, just that seems to encourage bad code\n> > practices in applications.\n> > \n> > > > > > Or is this useful for ABI compliance validation ?\n> > > > > >\n> > > > > > > ---\n> > > > > > >   include/libcamera/control_ids.h.in | 1 +\n> > > > > > >   1 file changed, 1 insertion(+)\n> > > > > > >\n> > > > > > > diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> > > > > > > index 5d0594c68..8f037589d 100644\n> > > > > > > --- a/include/libcamera/control_ids.h.in\n> > > > > > > +++ b/include/libcamera/control_ids.h.in\n> > > > > > > @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n> > > > > > >   extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n> > > > > > >   {% endif -%}\n> > > > > > >   extern const Control<{{ctrl.type}}> {{ctrl.name}};\n> > > > > > > +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n\nThis honestly seems pretty 'cheap' and valuable. ... I think it's a good\nidea ...\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> > > > > > >   {% endfor -%}\n> > > > > > >\n> > > > > > >   {% if vendor != 'libcamera' %}\n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id B02B6C32F5\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Mar 2025 23:35:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A44A268942;\n\tWed, 19 Mar 2025 00:35:15 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6D8A7617F8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 19 Mar 2025 00:35:13 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D10A655A;\n\tWed, 19 Mar 2025 00:33:30 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"VyFt9MX7\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742340810;\n\tbh=MaXgQ2iXTT81EyA+8ZZd7Q29LtnG7cPboT9ftuu5sTA=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=VyFt9MX7TTqTKSabRLjZNbSuerl/y7RZzkOzIkIbLQQJLvXJhNUEc/OafV8v3ddRI\n\t9IcdvyYKiX/Y9ThCcFzrRrwtI/nP/3vwFWKXlRbgdDLnOlA71N5Kvbzf4Mf0VDHJuI\n\tj7rvBIgtZfyHtYwy+wWD21k1AQfV7ZRjRwCt5/HI=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20250318204357.GD22890@pendragon.ideasonboard.com>","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>\n\t<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>\n\t<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>\n\t<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>\n\t<20250318150015.GD10085@pendragon.ideasonboard.com>\n\t<x7qmcry4m22r2euhvkvvkejbr3v6qto4krqbroxxhsl72e7prw@x5ivrqsajwii>\n\t<20250318204357.GD22890@pendragon.ideasonboard.com>","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>","Date":"Tue, 18 Mar 2025 23:35:10 +0000","Message-ID":"<174234091073.3286393.9194435253968802739@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33659,"web_url":"https://patchwork.libcamera.org/comment/33659/","msgid":"<6636ef0e-c52d-426e-8ecf-77504905cd11@ideasonboard.com>","date":"2025-03-20T10:24:11","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n\n2025. 03. 18. 21:43 keltezéssel, Laurent Pinchart írta:\n> On Tue, Mar 18, 2025 at 06:22:45PM +0100, Jacopo Mondi wrote:\n>> On Tue, Mar 18, 2025 at 05:00:15PM +0200, Laurent Pinchart wrote:\n>>> On Tue, Mar 18, 2025 at 09:11:27AM +0100, Jacopo Mondi wrote:\n>>>> On Mon, Mar 17, 2025 at 10:00:20PM +0100, Barnabás Pőcze wrote:\n>>>>> 2025. 03. 17. 19:54 keltezéssel, Jacopo Mondi írta:\n>>>>>> On Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n>>>>>>> Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n>>>>>>> for each control so that its existence can be checked easily\n>>>>>>> and without extra version checks.\n>>>>>>>\n>>>>>>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n>>>>>>\n>>>>>> Do we really want this ?\n>>>>>\n>>>>> Good question, hence the RFC; I don't think there is a very nice\n>>>>> way to discover (and use) controls at comptime/runtime. Also note\n>>>>\n>>>> What would the use case be ?\n>>>>\n>>>>> that the control namespaces already have their own existence macros\n>>>>> (e.g. `LIBCAMERA_HAS_RPI_VENDOR_CONTROLS`).\n>>>>\n>>>>>\n>>>>>> Applications should discover controls\n>>>>>> programmatically.\n>>>>>\n>>>>> What do you have in mind? Looking up the numeric id in the appropriate\n>>>>> `ControlIdMap` by the (namespace, name) pair?\n>>>>\n>>>> If you mean Camera::controls() and Camera::properties() then yes, I\n>>>> think applications should enumerate the supported controls from there\n>>>> and not rely on compile-time defines, as even if a control is defined\n>>>> it doesn't mean it is supported by the camera.\n>>>\n>>> True, but an application that would check if Camera::controls()\n>>> contains, for instance, controls::AE_ENABLE with\n>>>\n>>> \tif (camera->controls().count(controls::AE_ENABLE))\n>>>\n>>> will not compile if the libcamera version it compiles against does not\n>>> define the AeEnable control. Barnabás' patch allows fixing that with\n>>> conditional compilation.\n\nWhat I had in mind specifically, was something like this:\n\n   const libcamera::ControlId *\n   find_libcamera_control(std::string_view name, std::string_view vendor = \"libcamera\")\n   {\n     for (const auto& [ id, ctrl ] : libcamera::controls::controls) {\n       if (ctrl->name() == name && ctrl->vendor() == vendor)\n         return ctrl;\n     }\n     return nullptr;\n   }\n\nthen during initialization, you can potentially do:\n\n   static const auto lc_Gamma = find_libcamera_control(\"Gamma\");\n   ...\n\nand then\n\n   if (lc_Gamma && camera->controls().count(lc_Gamma->id())) {\n     /* libcamera has the Gamma control and the camera supports it */\n   }\n\nThen the set of controls supported (only) depends on the runtime version\nof libcamera, not the comptime one.\n\nWith the proposed macro, the comptime version has to know about the control\nin order for it to be supported in any way, so it admittedly cannot support\nthe scenario where the runtime version is upgraded to a new one that supports\nthe \"new\" controls. However, this also means that you can potentially get\nmore type safety since you have access to the `Control<...>` object with\nthe type information.\n\nSo maybe the best of both worlds could be had by merging the two into something\nlike this:\n\n   template<typename T>\n   const Control<T> *\n   findControl(const ControlIdMap& m, std::string_view name, std::string_view vendor = \"libcamera\")\n   {\n     for (const auto& [ id, ctrl ] : m) {\n       if (ctrl->name() == name && ctrl->vendor() == vendor) {\n          if (/* `ctrl` is appropriate for type `T` /*)\n            return static_cast<const Control<T> *>(ctrl);\n\n          /* warning or something */\n          break;\n       }\n     }\n     return nullptr;\n   }\n\nand then user code could define the controls they wish to use:\n\n   static const auto lc_gamma = libcamera::findControl<float>(libcamera::controls::controls, \"Gamma\");\n   static const auto lc_model = libcamera::findControl<std::string>(libcamera::properties::properties, \"Model\");\n   ...\n\nAnd then `ControlList` could be change to also accept pointers to `Control<T>`\nand ignore `nullptr`s. Yes, this version requires that the user code repeats\nthe type, but not sure if that can reasonably be avoided, and this is still\nmost likely better than manually setting up the `ControlValue` instances, etc.\n\n>>\n>> Do we really want applications to #ifdef on controls ?? I thought\n>> controls are part of ABI, so once an application knows which version\n>> of libcamera it link against, the list of defined controls should be\n>> fixed. But yes, we don't have ABI stability, so...\n> \n> Version checks are another option, I'm not against that.\n\nIf I had to argue, I would say version checks hide the intent more than a\ndedicated mechanism, and they can be caught off guard by back-porting.\n\nIn any case, I just wanted to see if there were any concrete plans or ideas\nregarding this question, hence the RFC patch.\n\n\nRegards,\nBarnabás Pőcze\n\n> \n>> Not that I'm against this patch, just that seems to encourage bad code\n>> practices in applications.\n>>\n>>>>>> Or is this useful for ABI compliance validation ?\n>>>>>>\n>>>>>>> ---\n>>>>>>>    include/libcamera/control_ids.h.in | 1 +\n>>>>>>>    1 file changed, 1 insertion(+)\n>>>>>>>\n>>>>>>> diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n>>>>>>> index 5d0594c68..8f037589d 100644\n>>>>>>> --- a/include/libcamera/control_ids.h.in\n>>>>>>> +++ b/include/libcamera/control_ids.h.in\n>>>>>>> @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n>>>>>>>    extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n>>>>>>>    {% endif -%}\n>>>>>>>    extern const Control<{{ctrl.type}}> {{ctrl.name}};\n>>>>>>> +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n>>>>>>>    {% endfor -%}\n>>>>>>>\n>>>>>>>    {% if vendor != 'libcamera' %}\n> \n> --\n> Regards,\n> \n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E1C24C3304\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 20 Mar 2025 10:24:18 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8E51E68951;\n\tThu, 20 Mar 2025 11:24:17 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9AE2368928\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 20 Mar 2025 11:24:15 +0100 (CET)","from [192.168.33.21] (185.221.143.221.nat.pool.zt.hu\n\t[185.221.143.221])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7AABF220;\n\tThu, 20 Mar 2025 11:22:31 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"BS6UyFIH\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742466151;\n\tbh=tibwWMsaF+yCI/bfSRyBD7HmyJ2P1CaxJh7NpcPq8Q8=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=BS6UyFIHJbyJYgGk1P7oF05gly/+RAsJhm/+P2+cHZzTZnuddoUAspFQuKF4+KQgp\n\t5WmGeSx53HuxJeKE0JqJGNucuAdNPF6CZgxJbwCtj2DKlWq2je7H5wMNHwEQCCSxqq\n\tw/tLsAP6aU4lHOm/taTNerJjbMa63iER6LCvSnhM=","Message-ID":"<6636ef0e-c52d-426e-8ecf-77504905cd11@ideasonboard.com>","Date":"Thu, 20 Mar 2025 11:24:11 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tJacopo Mondi <jacopo.mondi@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>\n\t<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>\n\t<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>\n\t<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>\n\t<20250318150015.GD10085@pendragon.ideasonboard.com>\n\t<x7qmcry4m22r2euhvkvvkejbr3v6qto4krqbroxxhsl72e7prw@x5ivrqsajwii>\n\t<20250318204357.GD22890@pendragon.ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20250318204357.GD22890@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":33696,"web_url":"https://patchwork.libcamera.org/comment/33696/","msgid":"<20250324211507.GB20035@pendragon.ideasonboard.com>","date":"2025-03-24T21:15:07","subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Mar 20, 2025 at 11:24:11AM +0100, Barnabás Pőcze wrote:\n> 2025. 03. 18. 21:43 keltezéssel, Laurent Pinchart írta:\n> > On Tue, Mar 18, 2025 at 06:22:45PM +0100, Jacopo Mondi wrote:\n> >> On Tue, Mar 18, 2025 at 05:00:15PM +0200, Laurent Pinchart wrote:\n> >>> On Tue, Mar 18, 2025 at 09:11:27AM +0100, Jacopo Mondi wrote:\n> >>>> On Mon, Mar 17, 2025 at 10:00:20PM +0100, Barnabás Pőcze wrote:\n> >>>>> 2025. 03. 17. 19:54 keltezéssel, Jacopo Mondi írta:\n> >>>>>> On Mon, Mar 17, 2025 at 07:11:46PM +0100, Barnabás Pőcze wrote:\n> >>>>>>> Generate a macro in the form of LIBCAMERA_HAS_$VENDOR_$MODE_$NAME\n> >>>>>>> for each control so that its existence can be checked easily\n> >>>>>>> and without extra version checks.\n> >>>>>>>\n> >>>>>>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> >>>>>>\n> >>>>>> Do we really want this ?\n> >>>>>\n> >>>>> Good question, hence the RFC; I don't think there is a very nice\n> >>>>> way to discover (and use) controls at comptime/runtime. Also note\n> >>>>\n> >>>> What would the use case be ?\n> >>>>\n> >>>>> that the control namespaces already have their own existence macros\n> >>>>> (e.g. `LIBCAMERA_HAS_RPI_VENDOR_CONTROLS`).\n> >>>>\n> >>>>>> Applications should discover controls\n> >>>>>> programmatically.\n> >>>>>\n> >>>>> What do you have in mind? Looking up the numeric id in the appropriate\n> >>>>> `ControlIdMap` by the (namespace, name) pair?\n> >>>>\n> >>>> If you mean Camera::controls() and Camera::properties() then yes, I\n> >>>> think applications should enumerate the supported controls from there\n> >>>> and not rely on compile-time defines, as even if a control is defined\n> >>>> it doesn't mean it is supported by the camera.\n> >>>\n> >>> True, but an application that would check if Camera::controls()\n> >>> contains, for instance, controls::AE_ENABLE with\n> >>>\n> >>> \tif (camera->controls().count(controls::AE_ENABLE))\n> >>>\n> >>> will not compile if the libcamera version it compiles against does not\n> >>> define the AeEnable control. Barnabás' patch allows fixing that with\n> >>> conditional compilation.\n> \n> What I had in mind specifically, was something like this:\n> \n>    const libcamera::ControlId *\n>    find_libcamera_control(std::string_view name, std::string_view vendor = \"libcamera\")\n>    {\n>      for (const auto& [ id, ctrl ] : libcamera::controls::controls) {\n>        if (ctrl->name() == name && ctrl->vendor() == vendor)\n>          return ctrl;\n>      }\n>      return nullptr;\n>    }\n> \n> then during initialization, you can potentially do:\n> \n>    static const auto lc_Gamma = find_libcamera_control(\"Gamma\");\n>    ...\n> \n> and then\n> \n>    if (lc_Gamma && camera->controls().count(lc_Gamma->id())) {\n>      /* libcamera has the Gamma control and the camera supports it */\n>    }\n> \n> Then the set of controls supported (only) depends on the runtime version\n> of libcamera, not the comptime one.\n\nIt's an interesting idea, albeit quite expensive.\n\n> With the proposed macro, the comptime version has to know about the control\n> in order for it to be supported in any way, so it admittedly cannot support\n> the scenario where the runtime version is upgraded to a new one that supports\n> the \"new\" controls.\n\nIf an application is compiled against an older version of libcamera and\nrun against a newer version, not being able to access newer controls\ndoesn't seem to be a severe limitation to me.\n\n> However, this also means that you can potentially get\n> more type safety since you have access to the `Control<...>` object with\n> the type information.\n\nThat's one of the features of the Control API that I like :-) It gets\nfairly dangerous at runtime otherwise.\n\n> So maybe the best of both worlds could be had by merging the two into something\n> like this:\n> \n>    template<typename T>\n>    const Control<T> *\n>    findControl(const ControlIdMap& m, std::string_view name, std::string_view vendor = \"libcamera\")\n>    {\n>      for (const auto& [ id, ctrl ] : m) {\n>        if (ctrl->name() == name && ctrl->vendor() == vendor) {\n>           if (/* `ctrl` is appropriate for type `T` /*)\n>             return static_cast<const Control<T> *>(ctrl);\n> \n>           /* warning or something */\n>           break;\n>        }\n>      }\n>      return nullptr;\n>    }\n> \n> and then user code could define the controls they wish to use:\n> \n>    static const auto lc_gamma = libcamera::findControl<float>(libcamera::controls::controls, \"Gamma\");\n>    static const auto lc_model = libcamera::findControl<std::string>(libcamera::properties::properties, \"Model\");\n>    ...\n> \n> And then `ControlList` could be change to also accept pointers to `Control<T>`\n> and ignore `nullptr`s. Yes, this version requires that the user code repeats\n> the type, but not sure if that can reasonably be avoided, and this is still\n> most likely better than manually setting up the `ControlValue` instances, etc.\n\nIs it worth it, compared to conditional compilation using the macros in\nthis patch ? I think we're trying with findControl() to fix a problem\nthat applications don't really suffer from. If they want to code\nsomething like the above I won't stop them, but making it possible to\ncheck at build time if a control is supported by the API seems better\nthan forcing each application to use a more complex method. The macros\nwill likely be even more useful with the plain C API.\n\n> >> Do we really want applications to #ifdef on controls ?? I thought\n> >> controls are part of ABI, so once an application knows which version\n> >> of libcamera it link against, the list of defined controls should be\n> >> fixed. But yes, we don't have ABI stability, so...\n> > \n> > Version checks are another option, I'm not against that.\n> \n> If I had to argue, I would say version checks hide the intent more than a\n> dedicated mechanism, and they can be caught off guard by back-porting.\n\nI think you're right. I tend to focus on upstream development instead of\nbackporting, but this patch is clean enough so I don't see a reason to\nmake backports more painful just for the sake of it :-)\n\n> In any case, I just wanted to see if there were any concrete plans or ideas\n> regarding this question, hence the RFC patch.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> >> Not that I'm against this patch, just that seems to encourage bad code\n> >> practices in applications.\n> >>\n> >>>>>> Or is this useful for ABI compliance validation ?\n> >>>>>>\n> >>>>>>> ---\n> >>>>>>>    include/libcamera/control_ids.h.in | 1 +\n> >>>>>>>    1 file changed, 1 insertion(+)\n> >>>>>>>\n> >>>>>>> diff --git a/include/libcamera/control_ids.h.in b/include/libcamera/control_ids.h.in\n> >>>>>>> index 5d0594c68..8f037589d 100644\n> >>>>>>> --- a/include/libcamera/control_ids.h.in\n> >>>>>>> +++ b/include/libcamera/control_ids.h.in\n> >>>>>>> @@ -49,6 +49,7 @@ extern const std::array<const ControlValue, {{ctrl.enum_values_count}}> {{ctrl.n\n> >>>>>>>    extern const std::map<std::string, {{ctrl.type}}> {{ctrl.name}}NameValueMap;\n> >>>>>>>    {% endif -%}\n> >>>>>>>    extern const Control<{{ctrl.type}}> {{ctrl.name}};\n> >>>>>>> +#define LIBCAMERA_HAS_{{vendor|upper}}_{{mode|upper}}_{{ctrl.name|snake_case|upper}}\n> >>>>>>>    {% endfor -%}\n> >>>>>>>\n> >>>>>>>    {% if vendor != 'libcamera' %}","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 5B9AEC0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 Mar 2025 21:15:32 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 804E768945;\n\tMon, 24 Mar 2025 22:15:31 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4AF8C6893F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Mar 2025 22:15:30 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 6910B455;\n\tMon, 24 Mar 2025 22:13:43 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"uALb2ynu\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1742850823;\n\tbh=1JMyWXPQrVS2w7UJzgFgK98WGa8W16voUhBmpNQBYm0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=uALb2ynuX3dkChtL9mdhWazrHmThaCfCcxIis85O6BIgsdQVTwWVAFrVHYwTX7/iH\n\tz8KTqf0AXTfEkIlOmU54jMvnvebgoD4Gcg3kE3JSP2G1xbac4TNpxi5hkNTifxMQFa\n\tWMwFzdK9QodgbNsHQ8abxUsNVicgN/E7TBf4FbK8=","Date":"Mon, 24 Mar 2025 23:15:07 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v1] libcamera: controls: Generate macro for each\n\tcontrol","Message-ID":"<20250324211507.GB20035@pendragon.ideasonboard.com>","References":"<20250317181146.214160-1-barnabas.pocze@ideasonboard.com>\n\t<ta67mej5eijc6qyegdxhnoz6bt3gwjpi2ggzyzmryxc5owf2xc@c3vetcgfz2ew>\n\t<e9eace45-756b-4999-92ef-e16b75e3028f@ideasonboard.com>\n\t<um4oqjwbmwyuma7nmsqaw3zpfiecmwcg25lrl6y6yu4x5e5mjg@pgsksr7q5hwr>\n\t<20250318150015.GD10085@pendragon.ideasonboard.com>\n\t<x7qmcry4m22r2euhvkvvkejbr3v6qto4krqbroxxhsl72e7prw@x5ivrqsajwii>\n\t<20250318204357.GD22890@pendragon.ideasonboard.com>\n\t<6636ef0e-c52d-426e-8ecf-77504905cd11@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<6636ef0e-c52d-426e-8ecf-77504905cd11@ideasonboard.com>","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]