xref: /aosp_15_r20/external/wayland/patches/0003-protocol-logger-test-Demonstrate-logging.diff (revision 84e872a0dc482bffdb63672969dd03a827d67c73)
1*84e872a0SLloyd PiqueFrom 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2*84e872a0SLloyd PiqueFrom: Lloyd Pique <[email protected]>
3*84e872a0SLloyd PiqueDate: Fri, 11 Mar 2022 17:57:37 -0800
4*84e872a0SLloyd PiqueSubject: [PATCH 3/6] protocol-logger-test: Demonstrate logging
5*84e872a0SLloyd Pique
6*84e872a0SLloyd PiqueClient message observers 3/6
7*84e872a0SLloyd Pique
8*84e872a0SLloyd PiqueAdds code demonstrating how to replicate the output produced by the internal
9*84e872a0SLloyd Piquewl_closure_print() using the client message observer interface.
10*84e872a0SLloyd Pique
11*84e872a0SLloyd PiqueIf you run protocol-logger-test with "WAYLAND_DEBUG=client", you can see the
12*84e872a0SLloyd Piqueclient messages logged to stderr twice, with the same strings.
13*84e872a0SLloyd Pique
14*84e872a0SLloyd PiqueSigned-off-by: Lloyd Pique <[email protected]>
15*84e872a0SLloyd Pique
16*84e872a0SLloyd Piquediff --git a/tests/protocol-logger-test.c b/tests/protocol-logger-test.c
17*84e872a0SLloyd Piqueindex 3b9dc3e..082f055 100644
18*84e872a0SLloyd Pique--- a/tests/protocol-logger-test.c
19*84e872a0SLloyd Pique+++ b/tests/protocol-logger-test.c
20*84e872a0SLloyd Pique@@ -80,6 +80,7 @@ struct client {
21*84e872a0SLloyd Pique 	struct wl_display *display;
22*84e872a0SLloyd Pique 	struct wl_callback *cb;
23*84e872a0SLloyd Pique 	struct wl_client_observer *sequence_observer;
24*84e872a0SLloyd Pique+	struct wl_client_observer *stderr_logger;
25*84e872a0SLloyd Pique
26*84e872a0SLloyd Pique 	struct expected_client_message *expected_msg;
27*84e872a0SLloyd Pique 	int expected_msg_count;
28*84e872a0SLloyd Pique@@ -190,6 +191,130 @@ client_sequence_observer_func(
29*84e872a0SLloyd Pique 		  "arg count mismatch: %s", details_msg);
30*84e872a0SLloyd Pique }
31*84e872a0SLloyd Pique
32*84e872a0SLloyd Pique+// A slightly simplified version of get_next_argument() from src/connection.c
33*84e872a0SLloyd Pique+static const char *
34*84e872a0SLloyd Pique+get_next_argument_type(const char *signature, char *type)
35*84e872a0SLloyd Pique+{
36*84e872a0SLloyd Pique+	for (; *signature; ++signature) {
37*84e872a0SLloyd Pique+		assert(strchr("iufsonah?", *signature) != NULL);
38*84e872a0SLloyd Pique+		switch (*signature) {
39*84e872a0SLloyd Pique+		case 'i':
40*84e872a0SLloyd Pique+		case 'u':
41*84e872a0SLloyd Pique+		case 'f':
42*84e872a0SLloyd Pique+		case 's':
43*84e872a0SLloyd Pique+		case 'o':
44*84e872a0SLloyd Pique+		case 'n':
45*84e872a0SLloyd Pique+		case 'a':
46*84e872a0SLloyd Pique+		case 'h':
47*84e872a0SLloyd Pique+			*type = *signature;
48*84e872a0SLloyd Pique+			return signature + 1;
49*84e872a0SLloyd Pique+		case '?':
50*84e872a0SLloyd Pique+			break;
51*84e872a0SLloyd Pique+		}
52*84e872a0SLloyd Pique+	}
53*84e872a0SLloyd Pique+	*type = 0;
54*84e872a0SLloyd Pique+	return signature;
55*84e872a0SLloyd Pique+}
56*84e872a0SLloyd Pique+
57*84e872a0SLloyd Pique+// This duplicates what the internal wl_closure_print function does, and can be
58*84e872a0SLloyd Pique+// used as a starting point for a client or server that wants to log messages.
59*84e872a0SLloyd Pique+static void
60*84e872a0SLloyd Pique+client_log_to_stderr_demo(void *user_data, enum wl_client_message_type type,
61*84e872a0SLloyd Pique+			  const struct wl_client_observed_message *message)
62*84e872a0SLloyd Pique+{
63*84e872a0SLloyd Pique+	int i;
64*84e872a0SLloyd Pique+	char arg_type;
65*84e872a0SLloyd Pique+	const char *signature = message->message->signature;
66*84e872a0SLloyd Pique+	const union wl_argument *args = message->arguments;
67*84e872a0SLloyd Pique+	struct wl_proxy *arg_proxy;
68*84e872a0SLloyd Pique+	const char *arg_class;
69*84e872a0SLloyd Pique+	struct timespec tp;
70*84e872a0SLloyd Pique+	unsigned long long time;
71*84e872a0SLloyd Pique+	FILE *f;
72*84e872a0SLloyd Pique+	char *buffer;
73*84e872a0SLloyd Pique+	size_t buffer_length;
74*84e872a0SLloyd Pique+
75*84e872a0SLloyd Pique+	f = open_memstream(&buffer, &buffer_length);
76*84e872a0SLloyd Pique+	if (f == NULL)
77*84e872a0SLloyd Pique+		return;
78*84e872a0SLloyd Pique+
79*84e872a0SLloyd Pique+	clock_gettime(CLOCK_REALTIME, &tp);
80*84e872a0SLloyd Pique+	time = (tp.tv_sec * 1000000LL) + (tp.tv_nsec / 1000);
81*84e872a0SLloyd Pique+
82*84e872a0SLloyd Pique+	// Note: server logger will be given message->resource, and should
83*84e872a0SLloyd Pique+	// use wl_resource_get_class and wl_resolurce_get_id.
84*84e872a0SLloyd Pique+	fprintf(f, "[%7llu.%03llu] %s%s%s%s%s@%u.%s(", time / 1000, time % 1000,
85*84e872a0SLloyd Pique+		(message->discarded_reason_str ? "discarded[" : ""),
86*84e872a0SLloyd Pique+		(message->discarded_reason_str ? message->discarded_reason_str
87*84e872a0SLloyd Pique+					       : ""),
88*84e872a0SLloyd Pique+		(message->discarded_reason_str ? "] " : ""),
89*84e872a0SLloyd Pique+		(type == WL_CLIENT_MESSAGE_REQUEST) ? " -> " : "",
90*84e872a0SLloyd Pique+		wl_proxy_get_class(message->proxy),
91*84e872a0SLloyd Pique+		wl_proxy_get_id(message->proxy), message->message->name);
92*84e872a0SLloyd Pique+
93*84e872a0SLloyd Pique+	for (i = 0; i < message->arguments_count; i++) {
94*84e872a0SLloyd Pique+		signature = get_next_argument_type(signature, &arg_type);
95*84e872a0SLloyd Pique+		if (i > 0)
96*84e872a0SLloyd Pique+			fprintf(f, ", ");
97*84e872a0SLloyd Pique+
98*84e872a0SLloyd Pique+		switch (arg_type) {
99*84e872a0SLloyd Pique+		case 'u':
100*84e872a0SLloyd Pique+			fprintf(f, "%u", args[i].u);
101*84e872a0SLloyd Pique+			break;
102*84e872a0SLloyd Pique+		case 'i':
103*84e872a0SLloyd Pique+			fprintf(f, "%d", args[i].i);
104*84e872a0SLloyd Pique+			break;
105*84e872a0SLloyd Pique+		case 'f':
106*84e872a0SLloyd Pique+			fprintf(f, "%f", wl_fixed_to_double(args[i].f));
107*84e872a0SLloyd Pique+			break;
108*84e872a0SLloyd Pique+		case 's':
109*84e872a0SLloyd Pique+			if (args[i].s)
110*84e872a0SLloyd Pique+				fprintf(f, "\"%s\"", args[i].s);
111*84e872a0SLloyd Pique+			else
112*84e872a0SLloyd Pique+				fprintf(f, "nil");
113*84e872a0SLloyd Pique+			break;
114*84e872a0SLloyd Pique+		case 'o':
115*84e872a0SLloyd Pique+			if (args[i].o) {
116*84e872a0SLloyd Pique+				// Note: server logger should instead cast to
117*84e872a0SLloyd Pique+				// wl_resource, and use wl_resource_get_class
118*84e872a0SLloyd Pique+				// and wl_resource_get_id.
119*84e872a0SLloyd Pique+				arg_proxy = (struct wl_proxy *)(args[i].o);
120*84e872a0SLloyd Pique+				arg_class = wl_proxy_get_class(arg_proxy);
121*84e872a0SLloyd Pique+
122*84e872a0SLloyd Pique+				fprintf(f, "%s@%u",
123*84e872a0SLloyd Pique+					arg_class ? arg_class : "[unknown]",
124*84e872a0SLloyd Pique+					wl_proxy_get_id(arg_proxy));
125*84e872a0SLloyd Pique+			} else {
126*84e872a0SLloyd Pique+				fprintf(f, "nil");
127*84e872a0SLloyd Pique+			}
128*84e872a0SLloyd Pique+			break;
129*84e872a0SLloyd Pique+		case 'n':
130*84e872a0SLloyd Pique+			fprintf(f, "new id %s@",
131*84e872a0SLloyd Pique+				(message->message->types[i])
132*84e872a0SLloyd Pique+					? message->message->types[i]->name
133*84e872a0SLloyd Pique+					: "[unknown]");
134*84e872a0SLloyd Pique+			if (args[i].n != 0)
135*84e872a0SLloyd Pique+				fprintf(f, "%u", args[i].n);
136*84e872a0SLloyd Pique+			else
137*84e872a0SLloyd Pique+				fprintf(f, "nil");
138*84e872a0SLloyd Pique+			break;
139*84e872a0SLloyd Pique+		case 'a':
140*84e872a0SLloyd Pique+			fprintf(f, "array");
141*84e872a0SLloyd Pique+			break;
142*84e872a0SLloyd Pique+		case 'h':
143*84e872a0SLloyd Pique+			fprintf(f, "fd %d", args[i].h);
144*84e872a0SLloyd Pique+			break;
145*84e872a0SLloyd Pique+		}
146*84e872a0SLloyd Pique+	}
147*84e872a0SLloyd Pique+
148*84e872a0SLloyd Pique+	fprintf(f, ")\n");
149*84e872a0SLloyd Pique+
150*84e872a0SLloyd Pique+	if (fclose(f) == 0) {
151*84e872a0SLloyd Pique+		fprintf(stderr, "%s", buffer);
152*84e872a0SLloyd Pique+		free(buffer);
153*84e872a0SLloyd Pique+	}
154*84e872a0SLloyd Pique+}
155*84e872a0SLloyd Pique+
156*84e872a0SLloyd Pique static void
157*84e872a0SLloyd Pique callback_done(void *data, struct wl_callback *cb, uint32_t time)
158*84e872a0SLloyd Pique {
159*84e872a0SLloyd Pique@@ -218,12 +343,15 @@ logger_setup(struct compositor *compositor, struct client *client)
160*84e872a0SLloyd Pique 	client->display = wl_display_connect(socket);
161*84e872a0SLloyd Pique 	client->sequence_observer = wl_display_create_client_observer(
162*84e872a0SLloyd Pique 		client->display, client_sequence_observer_func, client);
163*84e872a0SLloyd Pique+	client->stderr_logger = wl_display_create_client_observer(
164*84e872a0SLloyd Pique+		client->display, client_log_to_stderr_demo, client);
165*84e872a0SLloyd Pique }
166*84e872a0SLloyd Pique
167*84e872a0SLloyd Pique static void
168*84e872a0SLloyd Pique logger_teardown(struct compositor *compositor, struct client *client)
169*84e872a0SLloyd Pique {
170*84e872a0SLloyd Pique 	wl_client_observer_destroy(client->sequence_observer);
171*84e872a0SLloyd Pique+	wl_client_observer_destroy(client->stderr_logger);
172*84e872a0SLloyd Pique 	wl_display_disconnect(client->display);
173*84e872a0SLloyd Pique
174*84e872a0SLloyd Pique 	wl_client_destroy(compositor->client);
175