Can I include a ChatGPT generated example in a GNU Licensed project that I then submit to OpenSUSE factory?
I suppose I might at least have to document that it is Chat-GPT generated which I believe means the code is in the public domain but that it cannot be copyrighted (because it is not written by a human).
Background:
I’ve written ddcutil-service, a D-BUS service that uses libddcutil/ddcutil to adjust external-monitor brightness, contrast, and other settings.
I wanted to see how much faster using the service from C would be than using the ddcutil command line interface. The service should be faster because the normal ddcutil command has to reprobe i2c each time it’s run. I asked Chat GPT-4o to write the code.
Here is the ChatGPT conversation:
I have a dbus service, could you write a gdbus client that calls either its SetVcp and GetVcp methods according to parameters passed on the command line? The XML defining the service is about 600 lines, can I paste it here for you to start with?
… paste …
Could you now write a gdbus client in C that calls either its SetVcp and GetVcp methods of the above service definition according to parameters passed on the command line?
… generated code …
You only have to pass one of the edid or the display_number, not both, can we alter the code to allow either to be provided?
…generated corrected code…
Actually, you do have to pass both to the service, but the display_number can be set to -1 when passing the edid, and the edid can be set to ‘’ when passing the display_number.
…generated corrected code…
Actually the service is a Session Bus service.
…generated corrected code…
The ‘i’ in specifications such as ‘(issi)’ means the argument should be passed as a integer value.
…generated corrected code…
You’ve reached your GPT-4o limit. Responses will use GPT-3.5 until your limit resets after 11:46 AM.
Running the resulting code
At this point there was only one error left, so I manually corrected it, and the program then worked properly:
# Set display 1 brightness (feature code 16) to 100 using the generated d-bus client:
/bin/time -p ./a.out SetVcp 1 16 100
SetVcp called successfully.
Error status: 0, Error message: OK
real 0.06
user 0.00
sys 0.00
Compared to the ddcutil command it is much faster, so avoiding the need to reinitialise/reprobe i2c is worthwhile:
# Set display 1 brightness (feature code 16=0x10) to 100 using the ddcutil command:
/bin/time -p ddcutil --display 1 setvcp 0x10 10
real 0.49
user 0.02
sys 0.41
So the answer a C program calling the service is about 7.5 time faster than running the ddcutil
command.
The coding experience
Working with ChatGPT-4o felt kind of like working with a new hiree. They could read the XML and code a competent effort without supervision. But they needed additional insights into the specification of the code, and also a little help on how dbus parameters need to be interpreted and specified for glib.
The generated code:
#include <gio/gio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void call_set_vcp(GDBusConnection *connection, int display_number, const char *edid_txt, guint8 vcp_code, guint16 vcp_new_value) {
GError *error = NULL;
GVariant *result;
result = g_dbus_connection_call_sync(connection,
"com.ddcutil.DdcutilService", // Bus name
"/com/ddcutil/DdcutilObject", // Object path
"com.ddcutil.DdcutilInterface", // Interface name
"SetVcp", // Method name
g_variant_new("(isyqu)", display_number, edid_txt, vcp_code, vcp_new_value),
G_VARIANT_TYPE("(is)"),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if (error) {
g_printerr("Error calling SetVcp: %s\n", error->message);
g_error_free(error);
} else {
g_print("SetVcp called successfully.\n");
gint error_status;
const gchar *error_message;
g_variant_get(result, "(is)", &error_status, &error_message);
g_print("Error status: %d, Error message: %s\n", error_status, error_message);
g_variant_unref(result);
}
}
static void call_get_vcp(GDBusConnection *connection, int display_number, const char *edid_txt, guint8 vcp_code) {
GError *error = NULL;
GVariant *result;
result = g_dbus_connection_call_sync(connection,
"com.ddcutil.DdcutilService", // Bus name
"/com/ddcutil/DdcutilObject", // Object path
"com.ddcutil.DdcutilInterface", // Interface name
"GetVcp", // Method name
g_variant_new("(isyu)", display_number, edid_txt, vcp_code, 0),
G_VARIANT_TYPE("(qqsis)"),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);
if (error) {
g_printerr("Error calling GetVcp: %s\n", error->message);
g_error_free(error);
} else {
g_print("GetVcp called successfully.\n");
guint16 vcp_current_value, vcp_max_value;
const gchar *vcp_formatted_value, *error_message;
gint error_status;
g_variant_get(result, "(qqsis)", &vcp_current_value, &vcp_max_value, &vcp_formatted_value, &error_status, &error_message);
g_print("VCP current value: %d, VCP max value: %d, Formatted value: %s\n", vcp_current_value, vcp_max_value, vcp_formatted_value);
g_print("Error status: %d, Error message: %s\n", error_status, error_message);
g_variant_unref(result);
}
}
int main(int argc, char *argv[]) {
if (argc < 4) {
g_printerr("Usage: %s <method> <display_number or edid> <vcp_code> [vcp_new_value]\n", argv[0]);
return 1;
}
const char *method = argv[1];
const char *display_or_edid = argv[2];
const char *vcp_code_str = argv[3];
const char *vcp_new_value_str = argc > 4 ? argv[4] : NULL;
int display_number = -1;
const char *edid_txt = "";
guint8 vcp_code = (guint8)atoi(vcp_code_str);
guint16 vcp_new_value = vcp_new_value_str ? (guint16)atoi(vcp_new_value_str) : 0;
if (strcmp(display_or_edid, "edid:") == 0) {
edid_txt = display_or_edid + 5;
} else {
display_number = atoi(display_or_edid);
}
GError *error = NULL;
GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
if (!connection) {
g_printerr("Error connecting to session bus: %s\n", error->message);
g_error_free(error);
return 1;
}
if (strcmp(method, "SetVcp") == 0) {
if (vcp_new_value_str == NULL) {
g_printerr("Usage for SetVcp: %s SetVcp <display_number or edid> <vcp_code> <vcp_new_value>\n", argv[0]);
return 1;
}
call_set_vcp(connection, display_number, edid_txt, vcp_code, vcp_new_value);
} else if (strcmp(method, "GetVcp") == 0) {
call_get_vcp(connection, display_number, edid_txt, vcp_code);
} else {
g_printerr("Unknown method: %s\n", method);
return 1;
}
g_object_unref(connection);
return 0;
}