Bug Summary

File:/shared/playproj/i2c/src/dw/dw_poll.c
Warning:line 119, column 16
Value stored to 'bs_removed_attached_buses' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dw_poll.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/shared/playproj/i2c/src/dw -fcoverage-compilation-dir=/shared/playproj/i2c/src/dw -resource-dir /usr/lib/llvm-20/lib/clang/20 -D HAVE_CONFIG_H -I . -I ../.. -I /usr/include/libdrm -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I ../../src -I ../../src/public -D _GLIBCXX_ASSERTIONS -D _GNU_SOURCE -D PIC -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib64/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-compound-token-split-by-macro -std=c11 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o dw_poll.plist -x c dw_poll.c
1/** @file dw_poll.c
2 *
3 * Watch for display changes without using UDEV
4 */
5
6// Copyright (C) 2018-2026 Sanford Rockowitz <rockowitz@minsoft.com>
7// SPDX-License-Identifier: GPL-2.0-or-later
8
9#include "config.h"
10#include "public/ddcutil_types.h"
11
12/** \cond */
13#include <assert.h>
14#include <errno(*__errno_location ()).h>
15#include <fcntl.h>
16#include <glib-2.0/glib.h>
17#include <libudev.h>
18#include <stdbool.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/stat.h>
22#include <unistd.h>
23#ifdef USE_X111
24#include <X11/Xlib.h>
25#endif
26
27#include "util/common_inlines.h"
28#include "util/coredefs.h"
29#include "util/data_structures.h"
30#include "util/dbus_util.h"
31#include "util/debug_util.h"
32#include "util/file_util.h"
33#include "util/glib_string_util.h"
34#include "util/glib_util.h"
35#include "util/libdrm_aux_util.h"
36#include "util/linux_util.h"
37#include "util/msg_util.h"
38#include "util/report_util.h"
39#include "util/string_util.h"
40#include "util/sysfs_filter_functions.h"
41#include "util/sysfs_i2c_util.h"
42#include "util/sysfs_util.h"
43#include "util/traced_function_stack.h"
44#include "util/udev_util.h"
45
46#include "base/core.h"
47#include "base/displays.h"
48#include "base/ddc_errno.h"
49#include "base/drm_connector_state.h"
50#include "base/i2c_bus_base.h"
51#include "base/linux_errno.h"
52#include "base/rtti.h"
53#include "base/sleep.h"
54/** \endcond */
55
56#include "sysfs/sysfs_dpms.h"
57#include "sysfs/sysfs_sys_drm_connector.h"
58
59#include "i2c/i2c_bus_core.h"
60
61#include "ddc/ddc_displays.h"
62#include "ddc/ddc_packet_io.h"
63#include "ddc/ddc_vcp.h"
64
65#include "dw_common.h"
66#include "dw_dref.h"
67#include "dw_recheck.h"
68#include "dw_status_events.h"
69#include "dw_udev2.h"
70#ifdef USE_X111
71#include "dw_xevent.h"
72#endif
73
74#include "dw_poll.h"
75
76
77// Trace class for this file
78static DDCA_Trace_Group TRACE_GROUP = DDCA_TRC_CONN;
79
80int nonudev_poll_loop_millisec = DEFAULT_UDEV_WATCH_LOOP_MILLISEC500; // 2000;
81int retry_thread_sleep_factor_millisec = WATCH_RETRY_THREAD_SLEEP_FACTOR_MILLISEC500;
82bool_Bool stabilize_added_buses_w_edid = false0; // if set, stabilize when displays added as well as removed
83bool_Bool recheck_thread_active = false0;
84GMutex process_event_mutex;
85
86
87STATICstatic void process_screen_change_event(
88 BS256Bit_Set_256* p_bs_attached_buses,
89 BS256Bit_Set_256* p_bs_buses_w_edid,
90 GArray * deferred_events,
91 GPtrArray * displays_to_recheck
92 )
93{
94 bool_Bool debug = false0;
95 DBGTRC_STARTING(debug, DDCA_TRC_CONN, "*p_bs_old_attached_buses -> %s",do { if (traced_function_stack_enabled) push_traced_function(
__func__); dbgtrc( (debug) || trace_callstack_call_depth >
0 || is_traced_callstack_call(__func__) ? DDCA_TRC_ALL : (DDCA_TRC_CONN
), 0x08, __func__, 96, "dw_poll.c", "Starting ""*p_bs_old_attached_buses -> %s"
, bs256_to_string_decimal_t(*p_bs_attached_buses, "", ",")); }
while(0)
96 bs256_to_string_decimal_t(*p_bs_attached_buses, "", ","))do { if (traced_function_stack_enabled) push_traced_function(
__func__); dbgtrc( (debug) || trace_callstack_call_depth >
0 || is_traced_callstack_call(__func__) ? DDCA_TRC_ALL : (DDCA_TRC_CONN
), 0x08, __func__, 96, "dw_poll.c", "Starting ""*p_bs_old_attached_buses -> %s"
, bs256_to_string_decimal_t(*p_bs_attached_buses, "", ",")); }
while(0)
;
97 DBGTRC_NOPREFIX(debug, DDCA_TRC_CONN, "*p_bs_buses_w_edid -> %s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_CONN), 0x00, __func__, 98, "dw_poll.c", " "
"*p_bs_buses_w_edid -> %s", bs256_to_string_decimal_t(*p_bs_buses_w_edid
, "", ","))
98 bs256_to_string_decimal_t(*p_bs_buses_w_edid, "", ","))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_CONN), 0x00, __func__, 98, "dw_poll.c", " "
"*p_bs_buses_w_edid -> %s", bs256_to_string_decimal_t(*p_bs_buses_w_edid
, "", ","))
;
99
100 BS256Bit_Set_256 bs_old_attached_buses = *p_bs_attached_buses;
101 BS256Bit_Set_256 bs_old_buses_w_edid = *p_bs_buses_w_edid;
102
103 BS256Bit_Set_256 bs_new_attached_buses = i2c_detect_attached_buses_as_bitset();
104#ifdef IGNORE_LAPTOPS
105 if (watch_laptops) {
106 bs_new_attached_buses = i2c_detect_attached_buses_as_bitset();
107 }
108 else {
109 // to check if laptop
110 // use i2c_new_bus_info(), i2c_check_bus_info() to check
111 // or i2c_get_bus_info() if want it to be persistent
112 }
113#endif
114 BS256Bit_Set_256 bs_new_buses_w_edid = i2c_filter_buses_w_edid_as_bitset(bs_new_attached_buses);
115
116 Bit_Set_256 bs_added_buses_w_edid = bs256_and_not(bs_new_buses_w_edid, bs_old_buses_w_edid);
117 Bit_Set_256 bs_removed_buses_w_edid = bs256_and_not(bs_old_buses_w_edid, bs_new_buses_w_edid);
118 Bit_Set_256 bs_added_attached_buses = bs256_and_not(bs_new_attached_buses, bs_old_attached_buses);
119 Bit_Set_256 bs_removed_attached_buses = bs256_and_not(bs_old_attached_buses, bs_new_attached_buses);
Value stored to 'bs_removed_attached_buses' during its initialization is never read
120#ifdef TMI
121 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_old_buses_w_edid(0): %s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 122, "dw_poll.c", " "
"bs_old_buses_w_edid(0): %s", bs256_to_string_decimal_t(bs_old_buses_w_edid
, "", ","))
122 bs256_to_string_decimal_t(bs_old_buses_w_edid, "", ","))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 122, "dw_poll.c", " "
"bs_old_buses_w_edid(0): %s", bs256_to_string_decimal_t(bs_old_buses_w_edid
, "", ","))
;
123 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_new_buses_edid(0): %s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 124, "dw_poll.c", " "
"bs_new_buses_edid(0): %s", bs256_to_string_decimal_t(bs_new_buses_w_edid
, "", ","))
124 bs256_to_string_decimal_t(bs_new_buses_w_edid, "", ","))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 124, "dw_poll.c", " "
"bs_new_buses_edid(0): %s", bs256_to_string_decimal_t(bs_new_buses_w_edid
, "", ","))
;
125#endif
126
127 if ( bs256_count(bs_removed_buses_w_edid) > 0 ||
128 (stabilize_added_buses_w_edid && bs256_count(bs_added_buses_w_edid) > 0)) {
129 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_old_attached_buses: %s", BS256_REPR(bs_old_attached_buses))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 129, "dw_poll.c", " "
"bs_old_attached_buses: %s", bs256_to_string_decimal_t(bs_old_attached_buses
, "", ","))
;
130 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_new_attached_buses: %s", BS256_REPR(bs_new_attached_buses))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 130, "dw_poll.c", " "
"bs_new_attached_buses: %s", bs256_to_string_decimal_t(bs_new_attached_buses
, "", ","))
;
131 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_old_buses_w_edid: %s", BS256_REPR(bs_old_buses_w_edid))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 131, "dw_poll.c", " "
"bs_old_buses_w_edid: %s", bs256_to_string_decimal_t(bs_old_buses_w_edid
, "", ","))
;
132 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_new_buses_edid: %s", BS256_REPR(bs_new_buses_w_edid))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 132, "dw_poll.c", " "
"bs_new_buses_edid: %s", bs256_to_string_decimal_t(bs_new_buses_w_edid
, "", ","))
;
133
134 bs_new_buses_w_edid = dw_stabilized_buses_bs(bs_new_buses_w_edid, bs256_count(bs_removed_buses_w_edid));
135
136 // bs_added_buses_w_edid was declared BS26, why shadowed?
137 bs_added_buses_w_edid = bs256_and_not(bs_new_buses_w_edid, bs_old_buses_w_edid);
138 bs_removed_buses_w_edid = bs256_and_not(bs_old_buses_w_edid, bs_new_buses_w_edid);
139 bs_added_attached_buses = bs256_and_not(bs_new_attached_buses, bs_old_attached_buses);
140 bs_removed_attached_buses = bs256_and_not(bs_old_attached_buses, bs_new_attached_buses);
141 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "After stabilization:")dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 141, "dw_poll.c", " "
"After stabilization:")
;
142 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_old_attached_buses: %s", BS256_REPR(bs_old_attached_buses))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 142, "dw_poll.c", " "
"bs_old_attached_buses: %s", bs256_to_string_decimal_t(bs_old_attached_buses
, "", ","))
;
143 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_new_attached_buses: %s", BS256_REPR(bs_new_attached_buses))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 143, "dw_poll.c", " "
"bs_new_attached_buses: %s", bs256_to_string_decimal_t(bs_new_attached_buses
, "", ","))
;
144 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_old_buses_w_edid: %s", BS256_REPR(bs_old_buses_w_edid))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 144, "dw_poll.c", " "
"bs_old_buses_w_edid: %s", bs256_to_string_decimal_t(bs_old_buses_w_edid
, "", ","))
;
145 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_new_buses_edid: %s", BS256_REPR(bs_new_buses_w_edid))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 145, "dw_poll.c", " "
"bs_new_buses_edid: %s", bs256_to_string_decimal_t(bs_new_buses_w_edid
, "", ","))
;
146 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_added_attached_buses: %s", BS256_REPR(bs_added_attached_buses))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 146, "dw_poll.c", " "
"bs_added_attached_buses: %s", bs256_to_string_decimal_t(bs_added_attached_buses
, "", ","))
;
147 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_removed_attached_buses: %s", BS256_REPR(bs_removed_attached_buses))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 147, "dw_poll.c", " "
"bs_removed_attached_buses: %s", bs256_to_string_decimal_t(
bs_removed_attached_buses, "", ","))
;
148 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_added_buses_w_edid: %s", BS256_REPR(bs_added_buses_w_edid))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 148, "dw_poll.c", " "
"bs_added_buses_w_edid: %s", bs256_to_string_decimal_t(bs_added_buses_w_edid
, "", ","))
;
149 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bs_removed_buses_w_edid: %s", BS256_REPR(bs_removed_buses_w_edid))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 149, "dw_poll.c", " "
"bs_removed_buses_w_edid: %s", bs256_to_string_decimal_t(bs_removed_buses_w_edid
, "", ","))
;
150 }
151 bs_old_buses_w_edid = bs_new_buses_w_edid;
152 bs_old_attached_buses = bs_new_attached_buses;
153
154 bool_Bool hotplug_change_handler_emitted = false0;
155 bool_Bool connected_buses_w_edid_changed = bs256_count(bs_removed_buses_w_edid) > 0 ||
156 bs256_count(bs_added_buses_w_edid) > 0;
157 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "connected_buses_changed = %s", SBOOL(connected_buses_w_edid_changed))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 157, "dw_poll.c", " "
"connected_buses_changed = %s", ( (connected_buses_w_edid_changed
) ? "true" : "false" ))
;
158 if (connected_buses_w_edid_changed) {
159 hotplug_change_handler_emitted = dw_hotplug_change_handler(
160 bs_removed_buses_w_edid,
161 bs_added_buses_w_edid,
162 deferred_events,
163 displays_to_recheck);
164 }
165
166 if (hotplug_change_handler_emitted)
167 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "hotplug_change_handler_emitted = %s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 168, "dw_poll.c", " "
"hotplug_change_handler_emitted = %s", sbool (hotplug_change_handler_emitted
))
168 sbool (hotplug_change_handler_emitted))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 168, "dw_poll.c", " "
"hotplug_change_handler_emitted = %s", sbool (hotplug_change_handler_emitted
))
;
169
170
171#ifdef WATCH_ASLEEP
172 if (watch_dpms) {
173 // DBGTRC_NOPREFIX(debug, TRACE_GROUP, "Before ddc_check_bus_asleep(), bs_sleepy_buses: %s",
174 // BS256_REPR(bs_sleepy_buses));
175 // emits dpms events directly or places them on deferred_events queue
176 bs_sleepy_buses = ddc_i2c_check_bus_asleep(
177 bs_old_buses_w_edid, bs_sleepy_buses, deferred_events);
178 // DBGTRC_NOPREFIX(debug, TRACE_GROUP, "After ddc_check_bus_asleep(), bs_sleepy_buses: %s",
179 // BS256_REPR(bs_sleepy_buses));
180 }
181#endif
182
183#ifdef ALT
184 if (watch_dpms) {
185 for (int ndx = 0; ndx < all_i2c_buses->len; ndx++) {
186 I2C_Bus_Info * businfo = g_ptr_array_index(all_i2c_buses, ndx)((all_i2c_buses)->pdata)[ndx];
187 // DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "ndx=%d, businfo=%p", ndx, businfo);
188 // DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bus=%d", businfo->busno);
189 if (businfo->flags & I2C_BUS_ADDR_0X50) {
190 // DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "bus=%d, I2C_BUS_ADDR_0X50 set", businfo->busno);
191 bool_Bool is_dpms_asleep = dpms_check_drm_asleep_by_businfo(businfo);
192 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "busno=%d, is_dpms_asleep=%s, last_checked_dpms_asleep=%s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 193, "dw_poll.c", " "
"busno=%d, is_dpms_asleep=%s, last_checked_dpms_asleep=%s", businfo
->busno, sbool(is_dpms_asleep), sbool(businfo->last_checked_dpms_asleep
))
193 businfo->busno, sbool(is_dpms_asleep), sbool(businfo->last_checked_dpms_asleep))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 193, "dw_poll.c", " "
"busno=%d, is_dpms_asleep=%s, last_checked_dpms_asleep=%s", businfo
->busno, sbool(is_dpms_asleep), sbool(businfo->last_checked_dpms_asleep
))
;
194 if (is_dpms_asleep != businfo->last_checked_dpms_asleep) {
195 Display_Ref * dref = ddc_get_dref_by_busno_or_connector(businfo->busno, NULL((void*)0), /*ignore_invalid*/ true1);
196 assert(dref)((dref) ? (void) (0) : __assert_fail ("dref", "dw_poll.c", 196
, __extension__ __PRETTY_FUNCTION__))
;
197 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "sleep change event for dref=%p->%s", dref, dref_repr_t(dref))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 197, "dw_poll.c", " "
"sleep change event for dref=%p->%s", dref, dref_repr_t(dref
))
;
198 DDCA_Display_Event_Type event_type = (is_dpms_asleep) ? DDCA_EVENT_DPMS_ASLEEP : DDCA_EVENT_DPMS_AWAKE;
199 dw_emit_or_queue_display_status_event(event_type, dref->drm_connector, dref, dref->io_path, NULL((void*)0));
200 businfo->last_checked_dpms_asleep = is_dpms_asleep;
201 }
202 }
203 }
204 }
205#endif
206
207 *p_bs_attached_buses = bs_old_attached_buses;
208 *p_bs_buses_w_edid = bs_old_buses_w_edid;
209
210 DBGTRC_DONE(debug, DDCA_TRC_CONN, "*p_bs_old_attached_buses -> %s",do { dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_CONN), 0x10, __func__, 211, "dw_poll.c", "Done "
"*p_bs_old_attached_buses -> %s", bs256_to_string_decimal_t
(*p_bs_attached_buses, "", ",")); if (traced_function_stack_enabled
) pop_traced_function(__func__); } while (0)
211 bs256_to_string_decimal_t(*p_bs_attached_buses, "", ","))do { dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_CONN), 0x10, __func__, 211, "dw_poll.c", "Done "
"*p_bs_old_attached_buses -> %s", bs256_to_string_decimal_t
(*p_bs_attached_buses, "", ",")); if (traced_function_stack_enabled
) pop_traced_function(__func__); } while (0)
;
212 DBGTRC_NOPREFIX(debug, DDCA_TRC_CONN, "*p_bs_buses_w_edid -> %s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_CONN), 0x00, __func__, 213, "dw_poll.c", " "
"*p_bs_buses_w_edid -> %s", bs256_to_string_decimal_t(*p_bs_buses_w_edid
, "", ","))
213 bs256_to_string_decimal_t(*p_bs_buses_w_edid, "", ","))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_CONN), 0x00, __func__, 213, "dw_poll.c", " "
"*p_bs_buses_w_edid -> %s", bs256_to_string_decimal_t(*p_bs_buses_w_edid
, "", ","))
;
214}
215
216
217void invoke_process_screen_change_event(
218 BS256Bit_Set_256* bs_old_attached_buses_loc,
219 BS256Bit_Set_256* bs_old_buses_w_edid_loc,
220 GArray* deferred_events,
221 GPtrArray* displays_to_recheck)
222{
223 bool_Bool debug = false0;
224 DBGTRC_STARTING(debug, DDCA_TRC_NONE, "")do { if (traced_function_stack_enabled) push_traced_function(
__func__); dbgtrc( (debug) || trace_callstack_call_depth >
0 || is_traced_callstack_call(__func__) ? DDCA_TRC_ALL : (DDCA_TRC_NONE
), 0x08, __func__, 224, "dw_poll.c", "Starting """); } while
(0)
;
225
226 DBGTRC_NOPREFIX(debug, TRACE_GROUP, "Locking master_dw_mutex, thread_id = %d", TID())dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x00, __func__, 226, "dw_poll.c", " "
"Locking master_dw_mutex, thread_id = %d", (intmax_t) tid())
;
227 g_mutex_lock(&master_dw_mutex);
228
229 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "locking process_event_mutex")dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 229, "dw_poll.c", " "
"locking process_event_mutex")
;
230 g_mutex_lock(&process_event_mutex);
231 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "Processing screen change event")dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 231, "dw_poll.c", " "
"Processing screen change event")
;
232 process_screen_change_event(bs_old_attached_buses_loc, bs_old_buses_w_edid_loc,
233 deferred_events, displays_to_recheck);
234 if (displays_to_recheck->len > 0) {
235 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "handling displays_to_recheck")dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 235, "dw_poll.c", " "
"handling displays_to_recheck")
;
236 int len = displays_to_recheck->len;
237 for (int ndx = len-1; ndx >= 0; ndx--) {
238 dw_put_recheck_queue(g_ptr_array_index(displays_to_recheck, ndx)((displays_to_recheck)->pdata)[ndx]);
239 g_ptr_array_remove_index(displays_to_recheck, ndx);
240 }
241#ifdef OLD
242 Recheck_Displays_Data * rdd = calloc(1, sizeof(Recheck_Displays_Data));
243 rdd->displays_to_recheck = displays_to_recheck;
244 rdd->deferred_event_queue = deferred_events;
245 g_thread_new("display_recheck_thread", // optional thread name
246 ddc_recheck_displays_func,
247 rdd);
248 displays_to_recheck = g_ptr_array_new();
249#endif
250 }
251 g_mutex_unlock(&process_event_mutex);
252 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "unlocked process_event_mutex")dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 252, "dw_poll.c", " "
"unlocked process_event_mutex")
;
253
254 DBGTRC_NOPREFIX(debug, TRACE_GROUP, "Unlocking master_dw_mutex, thread_id = %d", TID())dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x00, __func__, 254, "dw_poll.c", " "
"Unlocking master_dw_mutex, thread_id = %d", (intmax_t) tid()
)
;
255 g_mutex_unlock(&master_dw_mutex);
256
257 DBGTRC_DONE(debug, DDCA_TRC_NONE, "")do { dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x10, __func__, 257, "dw_poll.c", "Done "
""); if (traced_function_stack_enabled) pop_traced_function(__func__
); } while (0)
;
258}
259
260
261
262/** Function that executes in the display watch thread.
263 *
264 * @param data pointer to a #Watch_Display_Data struct
265 */
266gpointer dw_watch_display_connections(gpointer data) {
267 bool_Bool debug = false0;
268 bool_Bool use_deferred_event_queue = false0;
269 Watch_Displays_Data * wdd = data;
270 assert(wdd && memcmp(wdd->marker, WATCH_DISPLAYS_DATA_MARKER, 4) == 0)((wdd && memcmp(wdd->marker, "WDDM", 4) == 0) ? (void
) (0) : __assert_fail ("wdd && memcmp(wdd->marker, WATCH_DISPLAYS_DATA_MARKER, 4) == 0"
, "dw_poll.c", 270, __extension__ __PRETTY_FUNCTION__))
;
271 assert(wdd->watch_mode == Watch_Mode_Xevent || wdd->watch_mode == Watch_Mode_Poll || wdd->watch_mode == Watch_Mode_Udev)((wdd->watch_mode == Watch_Mode_Xevent || wdd->watch_mode
== Watch_Mode_Poll || wdd->watch_mode == Watch_Mode_Udev)
? (void) (0) : __assert_fail ("wdd->watch_mode == Watch_Mode_Xevent || wdd->watch_mode == Watch_Mode_Poll || wdd->watch_mode == Watch_Mode_Udev"
, "dw_poll.c", 271, __extension__ __PRETTY_FUNCTION__))
;
272#ifdef USE_X111
273 if (wdd->watch_mode == Watch_Mode_Xevent)
274 assert(wdd->evdata)((wdd->evdata) ? (void) (0) : __assert_fail ("wdd->evdata"
, "dw_poll.c", 274, __extension__ __PRETTY_FUNCTION__))
;
275#endif
276 GPtrArray * displays_to_recheck = g_ptr_array_new();
277
278 DBGTRC_STARTING(debug, TRACE_GROUP,do { if (traced_function_stack_enabled) push_traced_function(
__func__); dbgtrc( (debug) || trace_callstack_call_depth >
0 || is_traced_callstack_call(__func__) ? DDCA_TRC_ALL : (TRACE_GROUP
), 0x08, __func__, 280, "dw_poll.c", "Starting ""Caller process id: %d, caller thread id: %d, our thread id: %d, event_classes=0x%02x, terminate_using_x11_event=%s"
, wdd->main_process_id, wdd->main_thread_id, tid(), wdd
->event_classes, sbool(terminate_using_x11_event)); } while
(0)
279 "Caller process id: %d, caller thread id: %d, our thread id: %d, event_classes=0x%02x, terminate_using_x11_event=%s",do { if (traced_function_stack_enabled) push_traced_function(
__func__); dbgtrc( (debug) || trace_callstack_call_depth >
0 || is_traced_callstack_call(__func__) ? DDCA_TRC_ALL : (TRACE_GROUP
), 0x08, __func__, 280, "dw_poll.c", "Starting ""Caller process id: %d, caller thread id: %d, our thread id: %d, event_classes=0x%02x, terminate_using_x11_event=%s"
, wdd->main_process_id, wdd->main_thread_id, tid(), wdd
->event_classes, sbool(terminate_using_x11_event)); } while
(0)
280 wdd->main_process_id, wdd->main_thread_id, tid(), wdd->event_classes, sbool(terminate_using_x11_event))do { if (traced_function_stack_enabled) push_traced_function(
__func__); dbgtrc( (debug) || trace_callstack_call_depth >
0 || is_traced_callstack_call(__func__) ? DDCA_TRC_ALL : (TRACE_GROUP
), 0x08, __func__, 280, "dw_poll.c", "Starting ""Caller process id: %d, caller thread id: %d, our thread id: %d, event_classes=0x%02x, terminate_using_x11_event=%s"
, wdd->main_process_id, wdd->main_thread_id, tid(), wdd
->event_classes, sbool(terminate_using_x11_event)); } while
(0)
;
281 DBGTRC_NOPREFIX(debug, TRACE_GROUP, "Watching for display connection events: %s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x00, __func__, 282, "dw_poll.c", " "
"Watching for display connection events: %s", sbool(wdd->event_classes
& DDCA_EVENT_CLASS_DISPLAY_CONNECTION))
282 sbool(wdd->event_classes & DDCA_EVENT_CLASS_DISPLAY_CONNECTION))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x00, __func__, 282, "dw_poll.c", " "
"Watching for display connection events: %s", sbool(wdd->event_classes
& DDCA_EVENT_CLASS_DISPLAY_CONNECTION))
;
283 DBGTRC_NOPREFIX(debug, TRACE_GROUP, "watch_mode = %s, watch_loop_millisec=%d", watch_mode_name(wdd->watch_mode), wdd->watch_loop_millisec)dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x00, __func__, 283, "dw_poll.c", " "
"watch_mode = %s, watch_loop_millisec=%d", watch_mode_name(wdd
->watch_mode), wdd->watch_loop_millisec)
;
284#ifdef WATCH_DPMS
285 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "Watching for dpms events: %s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 286, "dw_poll.c", " "
"Watching for dpms events: %s", sbool(wdd->event_classes &
DDCA_EVENT_CLASS_DPMS))
286 sbool(wdd->event_classes & DDCA_EVENT_CLASS_DPMS))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 286, "dw_poll.c", " "
"Watching for dpms events: %s", sbool(wdd->event_classes &
DDCA_EVENT_CLASS_DPMS))
;
287#endif
288
289 // may need to wait on startup
290 while (!all_i2c_buses) {
291 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "Waiting 1 sec for all_i2c_buses")dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 291, "dw_poll.c", " "
"Waiting 1 sec for all_i2c_buses")
;
292 SYSLOG2(DDCA_SYSLOG_NOTICE, "Waiting 1 sec for all_i2c_buses")do { if (test_emit_syslog(DDCA_SYSLOG_NOTICE)) { int syslog_priority
= syslog_importance_from_ddcutil_syslog_level(DDCA_SYSLOG_NOTICE
); if (syslog_priority >= 0) { char * body = g_strdup_printf
("Waiting 1 sec for all_i2c_buses"); syslog(syslog_priority, "[%6jd]"
" %s%s", (intmax_t) tid(), body, (tag_output) ? " (P)" : "" )
; free(body); } } } while(0)
;
293 SLEEP_MILLIS_WITH_STATS(500)do { loggable_sleep(500, SLEEP_OPT_STATS, DDCA_SYSLOG_NEVER, __func__
, 293, "dw_poll.c", ((void*)0)); } while(0)
;
294 }
295
296 pid_t cur_pid = getpid();
297 pid_t cur_tid = get_thread_id();
298 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "Our process id: %d, our thread id: %d", cur_pid, cur_tid)dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 298, "dw_poll.c", " "
"Our process id: %d, our thread id: %d", cur_pid, cur_tid)
;
299
300#ifdef WATCH_DPMS
301 bool_Bool watch_dpms = wdd->event_classes & DDCA_EVENT_CLASS_DPMS;
302 BS256Bit_Set_256 bs_sleepy_buses = EMPTY_BIT_SET_256;
303#endif
304
305#ifdef LAPTOPS_IGNORABLE
306 BS256Bit_Set_256 bs_old_attached_buses;
307 BS256Bit_Set_256 bs_old_buses_w_edid;
308if (watch_laptops) {
309 bs_old_attached_buses = i2c_buses_bitset_from_businfo_array(all_i2c_buses, false0);
310 bs_old_buses_w_edid = i2c_buses_bitset_from_businfo_array(all_i2c_buses, true1);
311}
312else {
313 bs_old_attached_buses = nonlaptop_buses_bitset_from_businfo_array(all_i2c_buses, false0);
314 bs_old_buses_w_edid = nonlaptop_buses_bitset_from_businfo_array(all_i2c_buses, true1);
315}
316#else
317 BS256Bit_Set_256 bs_old_attached_buses = i2c_buses_bitset_from_businfo_array(all_i2c_buses, false0);
318 BS256Bit_Set_256 bs_old_buses_w_edid = i2c_buses_bitset_from_businfo_array(all_i2c_buses, true1);
319#endif
320
321 DBGTRC_NOPREFIX(debug, TRACE_GROUP, "Initial i2c buses with edids: %s",dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x00, __func__, 322, "dw_poll.c", " "
"Initial i2c buses with edids: %s", bs256_to_string_decimal_t
(bs_old_buses_w_edid, "", ","))
322 BS256_REPR(bs_old_buses_w_edid))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x00, __func__, 322, "dw_poll.c", " "
"Initial i2c buses with edids: %s", bs256_to_string_decimal_t
(bs_old_buses_w_edid, "", ","))
;
323 if (IS_DBGTRC(debug, DDCA_TRC_NONE)( (debug) || is_tracing((DDCA_TRC_NONE), "dw_poll.c", __func__
) )
&& false0) {
324 rpt_vstring(0, "Initial I2C buses:");
325 i2c_dbgrpt_buses_summary(1);
326 rpt_vstring(0, "Initial Display Refs:");
327 ddc_dbgrpt_display_refs_summary(true1, // include_invalid_displays
328 false0, // report_businfo
329 1); // depth
330 if (use_drm_connector_states) {
331 rpt_vstring(0, "Initial DRM connector states");
332 report_drm_connector_states_basic(/*refresh*/ true1, 1);
333 }
334 }
335
336 GArray * deferred_events = NULL((void*)0);
337 if (use_deferred_event_queue) {
338 deferred_events = g_array_new(false0, // zero_terminated
339 false0, // clear
340 sizeof(DDCA_Display_Status_Event));
341 }
342
343 if (wdd->watch_mode == Watch_Mode_Udev) {
344 dw_udev_setup();
345 }
346
347 bool_Bool skip_next_sleep = false0;
348 int slept_millisec = 0; // will contain length of final sleep
349
350 while (!terminate_watch_thread) {
351 if (deferred_events && deferred_events->len > 0) {
352 dw_emit_deferred_events(deferred_events);
353 }
354 else { // skip polling loop sleep if deferred events were output
355 if (!skip_next_sleep && wdd->watch_mode == Watch_Mode_Poll) {
356 slept_millisec = dw_split_sleep(wdd->watch_loop_millisec);
357 }
358 }
359 skip_next_sleep = false0;
360 if (terminate_watch_thread)
361 continue;
362 dw_terminate_if_invalid_thread_or_process(cur_pid, cur_tid);
363
364 if (wdd->watch_mode == Watch_Mode_Udev) {
365 // sem_wait(&sem);
366 // close the door behind us:
367 // sem_post(&sem);
368 dw_udev_watch(wdd->watch_loop_millisec);
369 if (terminate_watch_thread)
370 continue;
371 }
372
373#ifdef USE_X111
374 else
375 if (wdd->watch_mode == Watch_Mode_Xevent) {
376 if (terminate_using_x11_event) {
377 bool_Bool event_found = dw_next_X11_event_of_interest(wdd->evdata);
378 // either display changed or terminate signaled
379 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "event_found=%s", sbool(event_found))dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 379, "dw_poll.c", " "
"event_found=%s", sbool(event_found))
;
380 if (!event_found) {
381 terminate_watch_thread = true1;
382 continue;
383 }
384 }
385
386 else {
387 bool_Bool event_found = dw_detect_xevent_screen_change(wdd->evdata, wdd->watch_loop_millisec);
388 if (event_found)
389 DBGTRC_NOPREFIX(debug, DDCA_TRC_NONE, "Screen change event occurred")dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (DDCA_TRC_NONE), 0x00, __func__, 389, "dw_poll.c", " "
"Screen change event occurred")
;
390 else
391 continue;
392 }
393 }
394#endif
395
396 bool_Bool paused = false0;
397#ifdef USE_DBUS1
398 uint64_t elapsed_ns = ldbus_elapsed_since_resume_from_sleep_ns();
399 uint64_t elapsed_ms = NANOS2MILLIS(elapsed_ns)(((elapsed_ns)+500000)/1000000);
400 char * msg = g_strdup_printf(
401 "Time since last return from sleep = %"PRIu64"l" "u"" ns = %"PRIu64"l" "u"" ms",
402 elapsed_ns, elapsed_ms);
403 DBGTRC(debug, TRACE_GROUP, "%s", msg)dbgtrc( (debug) ? DDCA_TRC_ALL : (TRACE_GROUP), 0x00, __func__
, 403, "dw_poll.c", "%s", msg)
;
404 BASIC_STD_FUNC_SYSLOG(LOG_WARNING, msg)do { char prefix[100] = {0}; get_msg_decoration(prefix, 100, 1
); syslog(4, "%s(%s) %s%s", prefix, __func__, msg, (tag_output
) ? " (N)" : "" ); } while(0)
;
405 free(msg);
406
407 if (elapsed_ms < pause_after_resume_ms) {
408 uint64_t remaining_sleep_ms = 1000 - elapsed_ms;
409 char * msg2 = g_strdup_printf("Pausing for %"PRIu64"l" "u", remaining_sleep_ms);
410 BASIC_STD_FUNC_SYSLOG(LOG_WARNING, msg2)do { char prefix[100] = {0}; get_msg_decoration(prefix, 100, 1
); syslog(4, "%s(%s) %s%s", prefix, __func__, msg2, (tag_output
) ? " (N)" : "" ); } while(0)
;
411 DBGTRC(debug, DDCA_TRC_NONE, "%s", msg2)dbgtrc( (debug) ? DDCA_TRC_ALL : (DDCA_TRC_NONE), 0x00, __func__
, 411, "dw_poll.c", "%s", msg2)
;
412 LOGGABLE_SLEEP(remaining_sleep_ms, SLEEP_OPT_TRACEABLE, LOG_WARNING, "%s", msg2)do { loggable_sleep(remaining_sleep_ms, SLEEP_OPT_TRACEABLE, 4
, __func__, 412, "dw_poll.c", "%s", msg2); } while(0)
;
413 free(msg2);
414 }
415#endif
416 if (recently_resumed_from_sleep_by_clocktime()) {
417 BASIC_STD_FUNC_SYSLOG(LOG_WARNING, "Recently resumed from sleep detected")do { char prefix[100] = {0}; get_msg_decoration(prefix, 100, 1
); syslog(4, "%s(%s) %s%s", prefix, __func__, "Recently resumed from sleep detected"
, (tag_output) ? " (N)" : "" ); } while(0)
;
418 if (paused) {
419 BASIC_STD_FUNC_SYSLOG(LOG_WARNING,do { char prefix[100] = {0}; get_msg_decoration(prefix, 100, 1
); syslog(4, "%s(%s) %s%s", prefix, __func__, "Already paused based on dbus notification. No additional pause."
, (tag_output) ? " (N)" : "" ); } while(0)
420 "Already paused based on dbus notification. No additional pause.")do { char prefix[100] = {0}; get_msg_decoration(prefix, 100, 1
); syslog(4, "%s(%s) %s%s", prefix, __func__, "Already paused based on dbus notification. No additional pause."
, (tag_output) ? " (N)" : "" ); } while(0)
;
421 }
422 else {
423 int delay_ms = 1000;
424 SIMPLE_STD_FUNC_SYSLOG(LOG_WARNING, "Pausing for %d millisec", delay_ms)do { char * body = g_strdup_printf("Pausing for %d millisec",
delay_ms); char prefix[100] = {0}; get_msg_decoration(prefix
, 100, 1); syslog(4, "%s(%s) %s%s", prefix, __func__, body, (
tag_output) ? " (N)" : "" ); free(body); } while(0)
;
425 dw_split_sleep(delay_ms);
426 }
427 }
428
429 invoke_process_screen_change_event(&bs_old_attached_buses, &bs_old_buses_w_edid,
430 deferred_events, displays_to_recheck);
431
432
433 } // while()
434
435 if (wdd->watch_mode == Watch_Mode_Udev) {
436 dw_udev_teardown();
437 }
438
439 // n. slept == 0 if no sleep was performed
440 DBGTRC_DONE(debug, TRACE_GROUP,do { dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x10, __func__, 441, "dw_poll.c", "Done "
"Terminating thread. Final polling sleep was %d millisec.", slept_millisec
); if (traced_function_stack_enabled) pop_traced_function(__func__
); } while (0)
441 "Terminating thread. Final polling sleep was %d millisec.", slept_millisec)do { dbgtrc( (debug) || trace_callstack_call_depth > 0 ? DDCA_TRC_ALL
: (TRACE_GROUP), 0x10, __func__, 441, "dw_poll.c", "Done "
"Terminating thread. Final polling sleep was %d millisec.", slept_millisec
); if (traced_function_stack_enabled) pop_traced_function(__func__
); } while (0)
;
442 g_ptr_array_free(displays_to_recheck, false0);
443 dw_free_watch_displays_data(wdd);
444 if (deferred_events)
445 g_array_free(deferred_events, true1);
446#ifdef WATCH_DPMS
447 if (watch_dpms)
448 g_ptr_array_free(sleepy_connectors, true1);
449#endif
450 free_current_traced_function_stack();
451 g_thread_exit(0);
452 assert(false)((0) ? (void) (0) : __assert_fail ("false", "dw_poll.c", 452,
__extension__ __PRETTY_FUNCTION__))
; // avoid clang warning re wdd use after free
453 return NULL((void*)0); // satisfy compiler check that value returned
454}
455
456
457void init_dw_poll() {
458 RTTI_ADD_FUNC(dw_watch_display_connections)rtti_func_name_table_add(dw_watch_display_connections, "dw_watch_display_connections"
);
;
459 RTTI_ADD_FUNC(invoke_process_screen_change_event)rtti_func_name_table_add(invoke_process_screen_change_event, "invoke_process_screen_change_event"
);
;
460 RTTI_ADD_FUNC(process_screen_change_event)rtti_func_name_table_add(process_screen_change_event, "process_screen_change_event"
);
;
461}