diff --git a/gui-agent/vmside.c b/gui-agent/vmside.c index 0bb51bb9..9db552c7 100644 --- a/gui-agent/vmside.c +++ b/gui-agent/vmside.c @@ -51,6 +51,7 @@ #include "list.h" #include "error.h" #include "encoding.h" +#include "unix-addr.h" #include #include #include "unistr.h" @@ -158,14 +159,38 @@ static struct genlist *windows_list; static struct genlist *embeder_list; static Ghandles *ghandles_for_vchan_reinitialize; -#define SKIP_NONMANAGED_WINDOW do { \ - if (!list_lookup(windows_list, window)) { \ - if (g->log_level > 0) \ - fprintf(stderr, "Skipping unmanaged window 0x%x\n", \ - (int) window); \ - return; \ - } \ -} while (0) +static void log_unmanaged_window(Ghandles *g, const char *context, XID window) { + if (g->log_level > 0) { + fprintf(stderr, + "%s: window 0x%lx not managed\n", + context, window); + } +} + +static struct genlist *lookup_window( + Ghandles *g, + struct genlist *list, + XID window, + const char *log_context) +{ + struct genlist *l = list_lookup(list, window); + if (l == NULL) { + if (log_context != NULL) { + log_unmanaged_window(g, log_context, window); + } + return NULL; + } + + if (l->data == NULL) { + // Should be unreachable. + fprintf(stderr, + "Error: list entry (for window 0x%lx) without data found!\n", + window); + exit(1); + } + + return l; +} /* Cursor name translation. See X11/cursorfont.h. */ @@ -304,11 +329,11 @@ static void send_event(Ghandles * g, const struct input_event *iev) { } g->created_input_device = 0; } - + // send syn const struct input_event syn = {.type = EV_SYN, .code = 0, .value = 0}; status = write(g->uinput_fd, &(syn), sizeof(struct input_event)); - + if ( status < 0 ) { if (g->log_level > 0) { fprintf(stderr, "writing SYN failed, falling back to xdriver. WRITE ERROR CODE: %d\n", status); @@ -333,11 +358,11 @@ static void process_xevent_damage(Ghandles * g, XID window, struct genlist *l; struct window_data *wd; - l = list_lookup(windows_list, window); + l = lookup_window(g, windows_list, window, __func__); if (!l) return; - wd = l->data; + if (wd->window_dump_pending) { send_pixmap_grant_refs(g, window); wd->window_dump_pending = False; @@ -409,7 +434,7 @@ static void process_xevent_cursor(Ghandles *g, XFixesCursorNotifyEvent *ev) if (!ret || window_under_pointer == None) return; - if (!list_lookup(windows_list, window_under_pointer)) + if (!lookup_window(g, windows_list, window_under_pointer, __func__)) return; cursor = find_cursor(g, ev->cursor_name); @@ -427,41 +452,37 @@ static void process_xevent_createnotify(Ghandles * g, XCreateWindowEvent * ev) int ret; ret = XGetWindowAttributes(g->display, ev->window, &attr); if (ret != 1) { - fprintf(stderr, "XGetWindowAttributes for 0x%x failed in " - "handle_create, ret=0x%x\n", (int) ev->window, - ret); + fprintf(stderr, "XGetWindowAttributes for 0x%lx failed in " + "handle_create, ret=0x%x\n", ev->window, ret); return; } if (g->log_level > 0) - fprintf(stderr, "Create for 0x%x class 0x%x\n", - (int) ev->window, attr.class); + fprintf(stderr, "Create for 0x%lx class 0x%x\n", + ev->window, attr.class); if (list_lookup(windows_list, ev->window)) { - fprintf(stderr, "CREATE for already existing 0x%x\n", - (int) ev->window); + fprintf(stderr, "CREATE for already existing 0x%lx\n", ev->window); return; } if (ev->parent != g->root_win) { /* GUI daemon no longer supports this */ fprintf(stderr, - "CREATE with non-root parent window 0x%x\n", - (unsigned int)ev->parent); + "CREATE with non-root parent window 0x%lx\n", ev->parent); return; } if (list_lookup(embeder_list, ev->window)) { /* ignore CreateNotify for embeder window */ if (g->log_level > 1) - fprintf(stderr, "CREATE for embeder 0x%x\n", - (int) ev->window); + fprintf(stderr, "CREATE for embeder 0x%lx\n", ev->window); return; } /* Initialize window_data structure */ wd = (struct window_data*)malloc(sizeof(struct window_data)); if (!wd) { - fprintf(stderr, "OUT OF MEMORY\n"); + fprintf(stderr, "%s: OUT OF MEMORY\n", __func__); return; } /* Default values for window_data. By default, window should receive InputFocus events */ @@ -514,7 +535,7 @@ static void feed_xdriver(Ghandles * g, int type, int arg1, int arg2) ret = read(g->xserver_fd, &ans, 1); if (ret != 1 || ans != '0') { perror("unix read"); - err(1, "read returned %zd, char read=0x%x\n", ret, (int) ans); + err(1, "read returned %zd, char read=0x%hhx\n", ret, ans); } } @@ -678,33 +699,37 @@ void send_wmname(Ghandles * g, XID window) write_message(g->vchan, hdr, msg); } -/* Retrieve the supported WM Protocols - We don't forward the info to dom0 as we only need specific client protocols - */ +/* + * Retrieve the supported WM Protocols + * + * We don't forward the info to dom0 as we only need specific client protocols. + */ void retrieve_wmprotocols(Ghandles * g, XID window, int ignore_fail) { int nitems; Atom *supported_protocols; int i; struct genlist *l; + struct window_data *wd; - if (!((l=list_lookup(windows_list, window)) && (l->data))) { - fprintf(stderr, "ERROR retrieve_wmprotocols: Window 0x%x data not initialized\n", (int)window); + l = lookup_window(g, windows_list, window, __func__); + if (!l) { return; } + wd = l->data; if (XGetWMProtocols(g->display, window, &supported_protocols, &nitems) == 1) { for (i=0; i < nitems; i++) { if (supported_protocols[i] == g->wm_take_focus) { if (g->log_level > 1) - fprintf(stderr, "Protocol take_focus supported for Window 0x%x\n", (int)window); + fprintf(stderr, "Protocol take_focus supported for Window 0x%lx\n", window); - ((struct window_data*)l->data)->support_take_focus = True; + wd->support_take_focus = True; } else if (supported_protocols[i] == g->wmDeleteWindow) { if (g->log_level > 1) - fprintf(stderr, "Protocol delete_window supported for Window 0x%x\n", (int)window); + fprintf(stderr, "Protocol delete_window supported for Window 0x%lx\n", window); - ((struct window_data*)l->data)->support_delete_window = True; + wd->support_delete_window = True; } } } else { @@ -716,18 +741,23 @@ void retrieve_wmprotocols(Ghandles * g, XID window, int ignore_fail) } -/* Retrieve the 'real' WMHints. - We don't forward the info to dom0 as we only need InputHint and dom0 doesn't care about it - */ +/* + * Retrieve the 'real' WMHints + * + * We don't forward the info to dom0 as we only need InputHint and dom0 doesn't + * care about it. + */ void retrieve_wmhints(Ghandles * g, XID window, int ignore_fail) { XWMHints *wm_hints; struct genlist *l; + struct window_data *wd; - if (!((l=list_lookup(windows_list, window)) && (l->data))) { - fprintf(stderr, "ERROR retrieve_wmhints: Window 0x%x data not initialized\n", (int)window); + l = lookup_window(g, windows_list, window, __func__); + if (!l) { return; } + wd = l->data; if (!(wm_hints = XGetWMHints(g->display, window))) { if (!ignore_fail) @@ -736,15 +766,15 @@ void retrieve_wmhints(Ghandles * g, XID window, int ignore_fail) } if (wm_hints->flags & InputHint) { - ((struct window_data*)l->data)->input_hint = wm_hints->input; + wd->input_hint = wm_hints->input; if (g->log_level > 1) - fprintf(stderr, "Received input hint 0x%x for Window 0x%x\n", wm_hints->input, (int)window); + fprintf(stderr, "Received input hint 0x%x for Window 0x%lx\n", wm_hints->input, window); } else { // Default value if (g->log_level > 1) - fprintf(stderr, "Received WMHints without input hint set for Window 0x%x\n", (int)window); - ((struct window_data*)l->data)->input_hint = True; + fprintf(stderr, "Received WMHints without input hint set for Window 0x%lx\n", window); + wd->input_hint = True; } XFree(wm_hints); } @@ -867,13 +897,17 @@ static void process_xevent_map(Ghandles * g, XID window) struct msg_hdr hdr; struct msg_map_info map_info; Window transient; + struct genlist *l; struct window_data *wd; - SKIP_NONMANAGED_WINDOW; - wd = list_lookup(windows_list, window)->data; + l = lookup_window(g, windows_list, window, __func__); + if (!l) { + return; + } + wd = l->data; if (g->log_level > 1) - fprintf(stderr, "MAP for window 0x%x\n", (int)window); + fprintf(stderr, "MAP for window 0x%lx\n", window); wd->window_dump_pending = True; send_window_state(g, window); XGetWindowAttributes(g->display, window, &attr); @@ -898,10 +932,13 @@ static void process_xevent_map(Ghandles * g, XID window) static void process_xevent_unmap(Ghandles * g, XID window) { struct msg_hdr hdr; - SKIP_NONMANAGED_WINDOW; + + if (!lookup_window(g, windows_list, window, __func__)) { + return; + } if (g->log_level > 1) - fprintf(stderr, "UNMAP for window 0x%x\n", (int)window); + fprintf(stderr, "UNMAP for window 0x%lx\n", window); hdr.type = MSG_UNMAP; hdr.window = window; hdr.untrusted_len = 0; @@ -914,28 +951,31 @@ static void process_xevent_destroy(Ghandles * g, XID window) { struct msg_hdr hdr; struct genlist *l; - /* embeders are not manged windows, so must be handled before SKIP_NONMANAGED_WINDOW */ - if ((l = list_lookup(embeder_list, window))) { - if (l->data) { - free(l->data); - } + struct window_data *wd; + + /* embeders are not manged windows, so must be handled first */ + l = lookup_window(g, embeder_list, window, NULL); + if (l) { + free(l->data); list_remove(l); + return; } - SKIP_NONMANAGED_WINDOW; + l = lookup_window(g, windows_list, window, __func__); + if (!l) { + return; + } + wd = l->data; if (g->log_level > 0) - fprintf(stderr, "handle destroy 0x%x\n", (int) window); + fprintf(stderr, "handle destroy 0x%lx\n", window); hdr.type = MSG_DESTROY; hdr.window = window; hdr.untrusted_len = 0; write_struct(g->vchan, hdr); - l = list_lookup(windows_list, window); - if (l->data) { - if (((struct window_data*)l->data)->is_docked) { - XDestroyWindow(g->display, ((struct window_data*)l->data)->embeder); - } - free(l->data); + if (wd->is_docked) { + XDestroyWindow(g->display, wd->embeder); } + free(l->data); list_remove(l); } @@ -945,40 +985,45 @@ static void process_xevent_configure(Ghandles * g, XID window, struct msg_hdr hdr; struct msg_configure conf; struct genlist *l; - /* SKIP_NONMANAGED_WINDOW; */ - if (!(l=list_lookup(windows_list, window))) { + struct window_data *wd = NULL; + + l = lookup_window(g, windows_list, window, NULL); + if (l) { + wd = l->data; + } else { /* if not real managed window, check if this is embeder for another window */ - struct genlist *e; - if ((e=list_lookup(embeder_list, window))) { + struct genlist *e = lookup_window(g, embeder_list, window, NULL); + if (e) { window = ((struct embeder_data*)e->data)->icon_window; if (!list_lookup(windows_list, window)) /* probably icon window have just destroyed, so ignore message */ - /* "l" not updated intentionally - when configure notify comes - * from the embeder, it should be passed to dom0 (in most cases as - * ACK for earlier configure request) */ return; + /* l and wd not updated intentionally - when configure notify comes + * from the embeder, it should be passed to dom0 (in most cases as + * ACK for earlier configure request) */ } else { /* ignore not managed windows */ + log_unmanaged_window(g, __func__, window); return; } } if (g->log_level > 1) fprintf(stderr, - "handle configure event 0x%x w=%d h=%d ovr=%d\n", - (int) window, ev->width, ev->height, - (int) ev->override_redirect); - if (l && l->data && ((struct window_data*)l->data)->is_docked) { + "handle configure event 0x%lx w=%d h=%d ovr=%d\n", + window, ev->width, ev->height, + ev->override_redirect); + if (wd && wd->is_docked) { /* for docked icon, ensure that it fills embeder window; don't send any * message to dom0 - it will be done for embeder itself*/ XWindowAttributes attr; int ret; - ret = XGetWindowAttributes(g->display, ((struct window_data*)l->data)->embeder, &attr); + ret = XGetWindowAttributes(g->display, wd->embeder, &attr); if (ret != 1) { fprintf(stderr, - "XGetWindowAttributes for 0x%x failed in " - "handle_xevent_configure, ret=0x%x\n", (int) ((struct window_data*)l->data)->embeder, ret); + "XGetWindowAttributes for 0x%lx failed in " + "handle_xevent_configure, ret=0x%x\n", wd->embeder, ret); return; } if (ev->x != 0 || ev->y != 0 || ev->width != attr.width || ev->height != attr.height) { @@ -1033,8 +1078,8 @@ static void handle_targets_list(Ghandles * g, unsigned char *data, int len) if (atoms[i] == g->utf8_string_atom) have_utf8 = 1; if (g->log_level > 1) - fprintf(stderr, "supported 0x%x %s\n", - (int) atoms[i], XGetAtomName(g->display, + fprintf(stderr, "supported 0x%lx %s\n", + atoms[i], XGetAtomName(g->display, atoms[i])); } XConvertSelection(g->display, g->clipboard, @@ -1158,9 +1203,8 @@ static void process_xevent_selection_req(Ghandles * g, if (resp.property == None) fprintf(stderr, - "Not supported selection_req target 0x%x %s\n", - (int) req->target, XGetAtomName(g->display, - req->target)); + "Not supported selection_req target 0x%lx %s\n", + req->target, XGetAtomName(g->display, req->target)); resp.type = SelectionNotify; resp.display = req->display; resp.requestor = req->requestor; @@ -1173,12 +1217,20 @@ static void process_xevent_selection_req(Ghandles * g, static void process_xevent_property(Ghandles * g, XID window, XPropertyEvent * ev) { + struct genlist *l; + struct window_data *wd; + g->time = ev->time; - SKIP_NONMANAGED_WINDOW; + + l = lookup_window(g, windows_list, window, __func__); + if (!l) { + return; + } + wd = l->data; + if (g->log_level > 1) - fprintf(stderr, "handle property %s for window 0x%x\n", - XGetAtomName(g->display, ev->atom), - (int) ev->window); + fprintf(stderr, "handle property %s for window 0x%lx\n", + XGetAtomName(g->display, ev->atom), ev->window); if (ev->atom == XA_WM_NAME) send_wmname(g, window); else if (ev->atom == g->net_wm_name) @@ -1192,13 +1244,12 @@ static void process_xevent_property(Ghandles * g, XID window, XPropertyEvent * e else if (ev->atom == g->wmProtocols) retrieve_wmprotocols(g,window, 0); else if (ev->atom == g->xembed_info) { - struct genlist *l = list_lookup(windows_list, window); Atom act_type; unsigned long nitems, bytesafter; unsigned char *data; int ret, act_fmt; - if (!l->data || !((struct window_data*)l->data)->is_docked) + if (wd->is_docked) /* ignore _XEMBED_INFO change on non-docked windows */ return; ret = XGetWindowProperty(g->display, window, g->xembed_info, 0, 2, False, @@ -1218,9 +1269,8 @@ static void process_xevent_property(Ghandles * g, XID window, XPropertyEvent * e static void process_xevent_message(Ghandles * g, XClientMessageEvent * ev) { if (g->log_level > 1) - fprintf(stderr, "handle message %s to window 0x%x\n", - XGetAtomName(g->display, ev->message_type), - (int) ev->window); + fprintf(stderr, "handle message %s to window 0x%lx\n", + XGetAtomName(g->display, ev->message_type), ev->window); if (ev->message_type == g->tray_opcode) { XClientMessageEvent resp; Window w; @@ -1239,14 +1289,14 @@ static void process_xevent_message(Ghandles * g, XClientMessageEvent * ev) case SYSTEM_TRAY_REQUEST_DOCK: w = ev->data.l[2]; - if (!(l=list_lookup(windows_list, w))) { - fprintf(stderr, "ERROR process_xevent_message: Window 0x%x not initialized\n", (int)w); + l = lookup_window(g, windows_list, w, "SYSTEM_TRAY_REQUEST_DOCK"); + if (!l) { return; } + wd = l->data; + if (g->log_level > 0) - fprintf(stderr, - "tray request dock for window 0x%x\n", - (int) w); + fprintf(stderr, "tray request dock for window 0x%lx\n", w); ret = XGetWindowProperty(g->display, w, g->xembed_info, 0, 2, False, g->xembed_info, &act_type, &act_fmt, &nitems, &bytesafter, &data); @@ -1264,11 +1314,6 @@ static void process_xevent_message(Ghandles * g, XClientMessageEvent * ev) if (ret == Success && nitems > 0) XFree(data); - if (!(l->data)) { - fprintf(stderr, "ERROR process_xevent_message: Window 0x%x data not initialized\n", (int)w); - return; - } - wd = (struct window_data*)(l->data); /* TODO: error checking */ wd->embeder = XCreateSimpleWindow(g->display, g->root_win, 0, 0, 32, 32, /* default icon size, will be changed by dom0 */ @@ -1278,13 +1323,11 @@ static void process_xevent_message(Ghandles * g, XClientMessageEvent * ev) g->screen)); wd->is_docked=True; if (g->log_level > 1) - fprintf(stderr, - " created embeder 0x%x\n", - (int) wd->embeder); + fprintf(stderr, "created embeder 0x%lx\n", wd->embeder); XSelectInput(g->display, wd->embeder, SubstructureNotifyMask); ed = (struct embeder_data*)malloc(sizeof(struct embeder_data)); if (!ed) { - fprintf(stderr, "OUT OF MEMORY\n"); + fprintf(stderr, "%s: OUT OF MEMORY\n", __func__); return; } ed->icon_window = w; @@ -1293,9 +1336,8 @@ static void process_xevent_message(Ghandles * g, XClientMessageEvent * ev) ret = XReparentWindow(g->display, w, wd->embeder, 0, 0); if (ret != 1) { fprintf(stderr, - "XReparentWindow for 0x%x failed in " - "handle_dock, ret=0x%x\n", (int) w, - ret); + "XReparentWindow for 0x%lx failed in " + "handle_dock, ret=0x%x\n", w, ret); return; } @@ -1335,8 +1377,8 @@ static void process_xevent_message(Ghandles * g, XClientMessageEvent * ev) struct msg_hdr hdr; struct msg_window_flags msg; - /* SKIP_NONMANAGED_WINDOW */ - if (!list_lookup(windows_list, ev->window)) return; + if (!lookup_window(g, windows_list, ev->window, "_NET_WM_STATE")) + return; msg.flags_set = 0; msg.flags_unset = 0; @@ -1347,12 +1389,12 @@ static void process_xevent_message(Ghandles * g, XClientMessageEvent * ev) msg.flags_set |= flags_from_atom(g, ev->data.l[1]); msg.flags_set |= flags_from_atom(g, ev->data.l[2]); } else if (ev->data.l[0] == 2) { /* toggle property */ - fprintf(stderr, "toggle window 0x%x property %s not supported, " - "please report it with the application name\n", (int) ev->window, + fprintf(stderr, "toggle window 0x%lx property %s not supported, " + "please report it with the application name\n", ev->window, XGetAtomName(g->display, ev->data.l[1])); } else { - fprintf(stderr, "invalid window state command (%ld) for window 0x%x" - "report with application name\n", ev->data.l[0], (int) ev->window); + fprintf(stderr, "invalid window state command (%ld) for window 0x%lx" + "report with application name\n", ev->data.l[0], ev->window); } hdr.window = ev->window; hdr.type = MSG_WINDOW_FLAGS; @@ -1409,22 +1451,28 @@ static void process_xevent(Ghandles * g) if (event_buffer.type == (damage_event + XDamageNotify)) { dev = (XDamageNotifyEvent *) & event_buffer; g->time = dev->timestamp; - // fprintf(stderr, "x=%hd y=%hd gx=%hd gy=%hd w=%hd h=%hd\n", - // dev->area.x, dev->area.y, dev->geometry.x, dev->geometry.y, dev->area.width, dev->area.height); + if (g->log_level > 1) { + fprintf(stderr, + "DamageNotify x=%hd y=%hd gx=%hd gy=%hd w=%hd h=%hd\n", + dev->area.x, dev->area.y, + dev->geometry.x, dev->geometry.y, + dev->area.width, dev->area.height); + } process_xevent_damage(g, dev->drawable, dev->area.x, dev->area.y, dev->area.width, dev->area.height); - // fprintf(stderr, "@"); } else if (event_buffer.type == (xfixes_event + XFixesCursorNotify)) { process_xevent_cursor( g, (XFixesCursorNotifyEvent *) &event_buffer); - } else if (g->log_level > 1) - fprintf(stderr, "#"); + } else if (g->log_level > 1) { + fprintf(stderr, + "%s: unhandled event of type %d\n", + __func__, event_buffer.type); + } } - } /* return 1 if info sent, 0 otherwise */ @@ -1446,16 +1494,14 @@ static int send_full_window_info(Ghandles *g, XID w, struct window_data *wd) const Window window_to_query = wd->is_docked ? wd->embeder : w; ret = XGetWindowAttributes(g->display, window_to_query, &attr); if (ret != 1) { - fprintf(stderr, "XGetWindowAttributes for 0x%x failed in " - "send_window_state, ret=0x%x\n", (int) w, - ret); + fprintf(stderr, "XGetWindowAttributes for 0x%lx failed in " + "send_window_state, ret=0x%x\n", w, ret); return 0; } ret = XQueryTree(g->display, window_to_query, &root, &parent, &children_list, &children_count); if (ret != 1) { - fprintf(stderr, "XQueryTree for 0x%x failed in " - "send_window_state, ret=0x%x\n", (int) w, - ret); + fprintf(stderr, "XQueryTree for 0x%lx failed in " + "send_window_state, ret=0x%x\n", w, ret); return 0; } if (children_list) @@ -1539,26 +1585,29 @@ static void send_all_windows_info(Ghandles *g) { static void wait_for_unix_socket(Ghandles *g) { struct sockaddr_un sockname, peer; - unsigned int addrlen; + socklen_t addrlen; int prev_umask; struct group *qubes_group; /* setup listening socket only once; in case of qubes_drv reconnections, * simply pickup next waiting connection there (using accept below) */ if (g->xserver_listen_fd == -1) { + addrlen = sockaddr_un_from_path(&sockname, SOCKET_ADDRESS); + if (addrlen == 0) { + fprintf(stderr, "invalid socket path: %s\n", SOCKET_ADDRESS); + exit(1); + } + unlink(SOCKET_ADDRESS); g->xserver_listen_fd = socket(AF_UNIX, SOCK_STREAM, 0); - memset(&sockname, 0, sizeof(sockname)); - sockname.sun_family = AF_UNIX; - memcpy(sockname.sun_path, SOCKET_ADDRESS, strlen(SOCKET_ADDRESS)); qubes_group = getgrnam("qubes"); if (qubes_group) prev_umask=umask(0007); else prev_umask=umask(0000); - if (bind(g->xserver_listen_fd, (struct sockaddr *) &sockname, sizeof(sockname)) == -1) { - printf("bind() failed\n"); + if (bind(g->xserver_listen_fd, (struct sockaddr *)&sockname, addrlen) == -1) { + fprintf(stderr, "bind() failed\n"); close(g->xserver_listen_fd); exit(1); } @@ -1601,7 +1650,7 @@ static void mkghandles(Ghandles * g) g->xserver_listen_fd = -1; g->xserver_fd = -1; - wait_for_unix_socket(g); // wait for Xorg qubes_drv to connect to us + wait_for_unix_socket(g); // wait for Xorg qubes_drv to connect to us do { g->display = XOpenDisplay(NULL); if (!g->display && errno != EAGAIN) { @@ -1612,8 +1661,8 @@ static void mkghandles(Ghandles * g) if (g->log_level > 0) fprintf(stderr, "Connection to local X server established.\n"); - g->screen = DefaultScreen(g->display); /* get CRT id number */ - g->root_win = RootWindow(g->display, g->screen); /* get default attributes */ + g->screen = DefaultScreen(g->display); /* get CRT id number */ + g->root_win = RootWindow(g->display, g->screen); /* get default attributes */ g->context = XCreateGC(g->display, g->root_win, 0, NULL); g->stub_win = XCreateSimpleWindow(g->display, g->root_win, 0, 0, 1, 1, @@ -1746,7 +1795,7 @@ static void handle_keypress(Ghandles * g, XID UNUSED(winid)) XFreeModifiermap(modmap); } } - + feed_xdriver(g, 'K', key.keycode, key.type == KeyPress ? 1 : 0); } else { int mod_mask; @@ -1755,7 +1804,7 @@ static void handle_keypress(Ghandles * g, XID UNUSED(winid)) iev.type = EV_KEY; XModifierKeymap *modmap; modmap = XGetModifierMapping(g->display); - + if (!modmap) { if (g->log_level > 0) fprintf(stderr, "failed to get modifier mapping\n"); @@ -1789,7 +1838,7 @@ static void handle_keypress(Ghandles * g, XID UNUSED(winid)) // update state for this modifier g->last_known_modifier_states ^= mod_mask; } - + // last modifier state was up, modifier has since been pressed down else if (!(g->last_known_modifier_states & mod_mask) && (key.state & mod_mask)) { iev.code = modmap->modifiermap[mod_index*modmap->max_keypermod] - 8; @@ -1802,7 +1851,7 @@ static void handle_keypress(Ghandles * g, XID UNUSED(winid)) } } } - + XFreeModifiermap(modmap); // caps lock needs to be excluded to not send down, up, down or down, up, up on a caps lock sync instead of down, up @@ -1811,27 +1860,32 @@ static void handle_keypress(Ghandles * g, XID UNUSED(winid)) iev.value = (key.type == KeyPress ? 1 : 0); send_event(g, &iev); } - + } } static void handle_button(Ghandles * g, XID winid) { struct msg_button key; - struct genlist *l = list_lookup(windows_list, winid); + struct genlist *l; + struct window_data *wd = NULL; + l = lookup_window(g, windows_list, winid, NULL); + if (l) { + wd = l->data; + } read_data(g->vchan, (char *) &key, sizeof(key)); - if (l && l->data && ((struct window_data*)l->data)->is_docked) { + if (wd && wd->is_docked) { /* get position of embeder, not icon itself*/ - winid = ((struct window_data*)l->data)->embeder; + winid = wd->embeder; XRaiseWindow(g->display, winid); } if (g->log_level > 1) fprintf(stderr, - "send buttonevent, win 0x%x type=%d button=%d\n", - (int) winid, key.type, key.button); + "send buttonevent, win 0x%lx type=%d button=%d\n", + winid, key.type, key.button); feed_xdriver(g, 'B', key.button, key.type == ButtonPress ? 1 : 0); } @@ -1841,18 +1895,24 @@ static void handle_motion(Ghandles * g, XID winid) // XMotionEvent event; XWindowAttributes attr; int ret; - struct genlist *l = list_lookup(windows_list, winid); + struct genlist *l; + struct window_data *wd = NULL; + + l = lookup_window(g, windows_list, winid, NULL); + if (l) { + wd = l->data; + } read_data(g->vchan, (char *) &key, sizeof(key)); - if (l && l->data && ((struct window_data*)l->data)->is_docked) { + if (wd && wd->is_docked) { /* get position of embeder, not icon itself*/ - winid = ((struct window_data*)l->data)->embeder; + winid = wd->embeder; } ret = XGetWindowAttributes(g->display, winid, &attr); if (ret != 1) { fprintf(stderr, - "XGetWindowAttributes for 0x%x failed in " - "do_button, ret=0x%x\n", (int) winid, ret); + "XGetWindowAttributes for 0x%lx failed in " + "do_button, ret=0x%x\n", winid, ret); return; } @@ -1866,13 +1926,19 @@ static void handle_crossing(Ghandles * g, XID winid) struct msg_crossing key; XWindowAttributes attr; int ret; - struct genlist *l = list_lookup(windows_list, winid); + struct genlist *l; + struct window_data *wd = NULL; + + l = lookup_window(g, windows_list, winid, NULL); + if (l) { + wd = l->data; + } /* we want to always get root window child (as this we get from * XQueryPointer and can compare to window_under_pointer), so for embeded * window get the embeder */ - if (l && l->data && ((struct window_data*)l->data)->is_docked) { - winid = ((struct window_data*)l->data)->embeder; + if (wd && wd->is_docked) { + winid = wd->embeder; } read_data(g->vchan, (char *) &key, sizeof(key)); @@ -1884,8 +1950,8 @@ static void handle_crossing(Ghandles * g, XID winid) ret = XGetWindowAttributes(g->display, winid, &attr); if (ret != 1) { fprintf(stderr, - "XGetWindowAttributes for 0x%x failed in " - "handle_crossing, ret=0x%x\n", (int) winid, ret); + "XGetWindowAttributes for 0x%lx failed in " + "handle_crossing, ret=0x%x\n", winid, ret); return; } @@ -1902,8 +1968,8 @@ static void handle_crossing(Ghandles * g, XID winid) &win_x, &win_y, &mask_return); if (ret != 1) { fprintf(stderr, - "XQueryPointer for 0x%x failed in " - "handle_crossing, ret=0x%x\n", (int) winid, + "XQueryPointer for 0x%lx failed in " + "handle_crossing, ret=0x%x\n", winid, ret); return; } @@ -1935,8 +2001,7 @@ static void take_focus(Ghandles * g, XID winid) ev.data.l[1] = g->time; XSendEvent(ev.display, ev.window, 1, 0, (XEvent *) & ev); if (g->log_level > 0) - fprintf(stderr, "WM_TAKE_FOCUS sent for 0x%x\n", - (int) winid); + fprintf(stderr, "WM_TAKE_FOCUS sent for 0x%lx\n", winid); } @@ -1944,6 +2009,7 @@ static void handle_focus(Ghandles * g, XID winid) { struct msg_focus key; struct genlist *l; + struct window_data *wd; int input_hint; int use_take_focus; @@ -1953,13 +2019,14 @@ static void handle_focus(Ghandles * g, XID winid) XRaiseWindow(g->display, winid); - if ( (l=list_lookup(windows_list, winid)) && (l->data) ) { - input_hint = ((struct window_data*)l->data)->input_hint; - use_take_focus = ((struct window_data*)l->data)->support_take_focus; - if (((struct window_data*)l->data)->is_docked) - XRaiseWindow(g->display, ((struct window_data*)l->data)->embeder); + l = lookup_window(g, windows_list, winid, "FocusIn"); + if (l) { + wd = l->data; + input_hint = wd->input_hint; + use_take_focus = wd->support_take_focus; + if (wd->is_docked) + XRaiseWindow(g->display, wd->embeder); } else { - fprintf(stderr, "WARNING handle_focus: FocusIn: Window 0x%x data not initialized\n", (int)winid); input_hint = True; use_take_focus = False; } @@ -1973,21 +2040,22 @@ static void handle_focus(Ghandles * g, XID winid) take_focus(g, winid); if (g->log_level > 1) - fprintf(stderr, "0x%x raised\n", (int) winid); + fprintf(stderr, "0x%lx raised\n", winid); } else if (key.type == FocusOut && (key.mode == NotifyNormal || key.mode == NotifyUngrab)) { - if ( (l=list_lookup(windows_list, winid)) && (l->data) ) - input_hint = ((struct window_data*)l->data)->input_hint; - else { - fprintf(stderr, "WARNING handle_focus: FocusOut: Window 0x%x data not initialized\n", (int)winid); + l = lookup_window(g, windows_list, winid, "FocusOut"); + if (l) { + wd = l->data; + input_hint = wd->input_hint; + } else { input_hint = True; } if (input_hint) XSetInputFocus(g->display, None, RevertToParent, g->time); if (g->log_level > 1) - fprintf(stderr, "0x%x lost focus\n", (int) winid); + fprintf(stderr, "0x%lx lost focus\n", winid); } } @@ -2018,12 +2086,19 @@ static void handle_keymap_notify(Ghandles * g) static void handle_configure(Ghandles * g, XID winid) { struct msg_configure r; - struct genlist *l = list_lookup(windows_list, winid); + struct genlist *l; + struct window_data *wd = NULL; XWindowAttributes attr; + + l = lookup_window(g, windows_list, winid, __func__); + if (l) { + wd = l->data; + } + XGetWindowAttributes(g->display, winid, &attr); read_data(g->vchan, (char *) &r, sizeof(r)); - if (l && l->data && ((struct window_data*)l->data)->is_docked) { - XMoveResizeWindow(g->display, ((struct window_data*)l->data)->embeder, r.x, r.y, r.width, r.height); + if (wd && wd->is_docked) { + XMoveResizeWindow(g->display, wd->embeder, r.x, r.y, r.width, r.height); XMoveResizeWindow(g->display, winid, 0, 0, r.width, r.height); } else { XMoveResizeWindow(g->display, winid, r.x, r.y, r.width, r.height); @@ -2046,19 +2121,20 @@ static void handle_map(Ghandles * g, XID winid) CWOverrideRedirect, &attr); XMapWindow(g->display, winid); if (g->log_level > 1) - fprintf(stderr, "map msg for 0x%x\n", (int) winid); + fprintf(stderr, "map msg for 0x%lx\n", winid); } static void handle_close(Ghandles * g, XID winid) { struct genlist *l; + struct window_data *wd; int use_delete_window; - if ( (l=list_lookup(windows_list, winid)) && (l->data) ) { - use_delete_window = ((struct window_data*)l->data)->support_delete_window; + l = lookup_window(g, windows_list, winid, __func__); + if (l) { + wd = l->data; + use_delete_window = wd->support_delete_window; } else { - fprintf(stderr, "WARNING handle_close: Window 0x%x data not initialized\n", - (int)winid); use_delete_window = True; /* gentler, though it may be a no-op */ } @@ -2073,13 +2149,11 @@ static void handle_close(Ghandles * g, XID winid) ev.data.l[0] = g->wmDeleteWindow; XSendEvent(ev.display, ev.window, 1, 0, (XEvent *) & ev); if (g->log_level > 0) - fprintf(stderr, "wmDeleteWindow sent for 0x%x\n", - (int) winid); + fprintf(stderr, "wmDeleteWindow sent for 0x%lx\n", winid); } else { XKillClient(g->display, winid); if (g->log_level > 0) - fprintf(stderr, "XKillClient() called for 0x%x\n", - (int) winid); + fprintf(stderr, "XKillClient() called for 0x%lx\n", winid); } } @@ -2136,8 +2210,7 @@ static void handle_clipboard_req(Ghandles * g, XID winid) #endif owner = XGetSelectionOwner(g->display, Clp); if (g->log_level > 0) - fprintf(stderr, "clipboard req, owner=0x%x\n", - (int) owner); + fprintf(stderr, "clipboard req, owner=0x%lx\n", owner); if (owner == None) { send_clipboard_data(g->vchan, winid, NULL, 0, g->protocol_version); return; @@ -2433,17 +2506,17 @@ int main(int argc, char **argv) g.uinput_fd = open("/dev/uinput", O_WRONLY | O_NDELAY); if(g.uinput_fd < 0) { g.uinput_fd = open("/dev/input/uinput", O_WRONLY | O_NDELAY); - + if(g.uinput_fd < 0) { fprintf(stderr, "Couldn't open uinput, falling back to xdriver\n"); g.created_input_device = 0; } } } - + // input device creation if(g.created_input_device) { - + if (ioctl(g.uinput_fd, UI_SET_EVBIT, EV_SYN) < 0) { fprintf(stderr, "error setting EVBIT for EV_SYN, falling back to xdriver\n"); g.created_input_device = 0; @@ -2460,22 +2533,22 @@ int main(int argc, char **argv) fprintf(stderr, "Not able to set KEYBIT %d\n", i); } } - + struct uinput_setup usetup; memset(&usetup, 0, sizeof(usetup)); strcpy(usetup.name, "Qubes Virtual Input Device"); - + if(ioctl(g.uinput_fd, UI_DEV_SETUP, &usetup) < 0) { fprintf(stderr, "Input device setup failed, falling back to xdriver\n"); g.created_input_device = 0; } else { - + if(ioctl(g.uinput_fd, UI_DEV_CREATE) < 0) { fprintf(stderr, "Input device creation failed, falling back to xdriver\n"); g.created_input_device = 0; } } - + g.last_known_modifier_states = 0; } diff --git a/include/unix-addr.h b/include/unix-addr.h new file mode 100644 index 00000000..d8f9af17 --- /dev/null +++ b/include/unix-addr.h @@ -0,0 +1,37 @@ +/* + * The Qubes OS Project, https://www.qubes-os.org/ + * + * Copyright (C) 2025 Simon Gaiser + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include + +static inline socklen_t sockaddr_un_from_path(struct sockaddr_un *addr, char *path) +{ + size_t len; + + memset(addr, 0, sizeof(*addr)); + addr->sun_family = AF_UNIX; + len = strlen(path); + if (len == 0 || len > sizeof(addr->sun_path) - 1) { + return 0; + } + memcpy(addr->sun_path, path, len); + return offsetof(typeof(*addr), sun_path) + len + 1; +} diff --git a/xf86-input-mfndev/src/qubes.c b/xf86-input-mfndev/src/qubes.c index 81eaecf0..3892dbd5 100644 --- a/xf86-input-mfndev/src/qubes.c +++ b/xf86-input-mfndev/src/qubes.c @@ -92,6 +92,7 @@ #include "xdriver-shm-cmd.h" #include "qubes.h" #include "labels.h" +#include "unix-addr.h" #include "../../xf86-qubes-common/include/xf86-qubes-common.h" @@ -388,19 +389,22 @@ static int _qubes_init_axes(DeviceIntPtr device) int connect_unix_socket(QubesDevicePtr pQubes); int connect_unix_socket(QubesDevicePtr pQubes) { - int s, len; + int s; struct sockaddr_un remote; + socklen_t len; + + len = sockaddr_un_from_path(&remote, pQubes->device); + if (len == 0) { + xf86Msg(X_ERROR, "invalid socket path: %s\n", pQubes->device); + return -1; + } if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { xf86Msg(X_ERROR, "socket(%s): %s\n", pQubes->device, strerror(errno)); return -1; } - - remote.sun_family = AF_UNIX; - strncpy(remote.sun_path, pQubes->device, sizeof(remote.sun_path)); - len = strlen(remote.sun_path) + sizeof(remote.sun_family); - if (connect(s, (struct sockaddr *) &remote, len) == -1) { + if (connect(s, (struct sockaddr *)&remote, len) == -1) { xf86Msg(X_ERROR, "connect(%s): %s\n", pQubes->device, strerror(errno)); close(s); return -1; diff --git a/xf86-video-dummy/src/dummy_driver.c b/xf86-video-dummy/src/dummy_driver.c index 5af1c6fe..9f8f3cb5 100644 --- a/xf86-video-dummy/src/dummy_driver.c +++ b/xf86-video-dummy/src/dummy_driver.c @@ -137,8 +137,8 @@ _X_EXPORT DriverRec DUMMY = { }; static SymTabRec DUMMYChipsets[] = { - { DUMMY_CHIP, "dummy" }, - { -1, NULL } + { DUMMY_CHIP, "dummy" }, + { -1, NULL } }; typedef enum { @@ -148,10 +148,10 @@ typedef enum { } DUMMYOpts; static const OptionInfoRec DUMMYOptions[] = { - { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_RENDER, "Render", OPTV_STRING, {0}, FALSE }, + { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_RENDER, "Render", OPTV_STRING, {0}, FALSE }, { OPTION_GUI_DOMID, "GUIDomID", OPTV_INTEGER, {0}, FALSE }, - { -1, NULL, OPTV_NONE, {0}, FALSE } + { -1, NULL, OPTV_NONE, {0}, FALSE } }; #ifdef XFree86LOADER @@ -568,7 +568,7 @@ DUMMYProbe(DriverPtr drv, int flags) for (i = 0; i < numUsed; i++) { ScrnInfoPtr pScrn = NULL; - int entityIndex = + int entityIndex = xf86ClaimNoSlot(drv,DUMMY_CHIP,devSections[i],TRUE); /* Allocate a ScrnInfoRec and claim the slot */ if ((pScrn = xf86AllocateScreen(drv,0 ))) { @@ -589,7 +589,7 @@ DUMMYProbe(DriverPtr drv, int flags) foundScreen = TRUE; } } - } + } return foundScreen; } @@ -609,21 +609,21 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) GDevPtr device = xf86GetEntityInfo(pScrn->entityList[0])->device; const char *render, *defaultRender = "/dev/dri/renderD128"; - if (flags & PROBE_DETECT) + if (flags & PROBE_DETECT) return TRUE; - + /* Allocate the DummyRec driverPrivate */ if (!DUMMYGetRec(pScrn)) { return FALSE; } - + dPtr = DUMMYPTR(pScrn); pScrn->chipset = (char *)xf86TokenToString(DUMMYChipsets, DUMMY_CHIP); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Chipset is a DUMMY\n"); - + pScrn->monitor = pScrn->confScreen->monitor; if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb)) @@ -668,7 +668,7 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) } } - if (!xf86SetDefaultVisual(pScrn, -1)) + if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; if (pScrn->depth > 1) { @@ -718,8 +718,8 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) clockRanges->ClockMulFactor = 1; clockRanges->minClock = 11000; /* guessed ยงยงยง */ clockRanges->maxClock = maxClock; - clockRanges->clockIndex = -1; /* programmable */ - clockRanges->interlaceAllowed = TRUE; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->interlaceAllowed = TRUE; clockRanges->doubleScanAllowed = TRUE; /* Subtract memory for HW cursor */ @@ -755,8 +755,8 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) * driver and if the driver doesn't provide code to set them. They * are not pre-initialised at all. */ - xf86SetCrtcForModes(pScrn, 0); - + xf86SetCrtcForModes(pScrn, 0); + /* Set the current mode to the first in the list */ pScrn->currentMode = pScrn->modes; @@ -774,7 +774,7 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) if (!xf86LoadSubModule(pScrn, "ramdac")) RETURN; } - + /* We have no contiguous physical fb in physical memory */ pScrn->memPhysBase = 0; pScrn->fbOffset = 0; @@ -784,7 +784,7 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) if (!render) render = defaultRender; - + dPtr->fd = open(render, O_RDWR); if (dPtr->fd < 0) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Open render %s fail\n", render); @@ -809,7 +809,7 @@ static Bool DUMMYEnterVT(VT_FUNC_ARGS_DECL) { SCRN_INFO_PTR(arg); - + /* Should we re-save the text mode on each VT enter? */ if(!dummyModeInit(pScrn, pScrn->currentMode)) return FALSE; @@ -843,7 +843,7 @@ DUMMYLoadPalette( shift = Gshift = 1; break; case 16: - shift = 0; + shift = 0; Gshift = 0; break; default: @@ -856,7 +856,7 @@ DUMMYLoadPalette( dPtr->colors[index].red = colors[index].red << shift; dPtr->colors[index].green = colors[index].green << Gshift; dPtr->colors[index].blue = colors[index].blue << shift; - } + } } @@ -1061,12 +1061,12 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) return FALSE; } - + /* * next we save the current state and setup the first mode */ dummySave(pScrn); - + if (!dummyModeInit(pScrn,pScrn->currentMode)) return FALSE; DUMMYAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); @@ -1075,9 +1075,9 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) * Reset visual list. */ miClearVisualTypes(); - + /* Setup the visuals we support. */ - + if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), pScrn->rgbBits, pScrn->defaultVisual)) @@ -1211,7 +1211,7 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) } /* XRANDR initialization end */ - + if (dPtr->swCursor) xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Software Cursor.\n"); @@ -1225,9 +1225,9 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) AvailFBArea.y1 = 0; AvailFBArea.x2 = pScrn->displayWidth; AvailFBArea.y2 = lines; - xf86InitFBManager(pScreen, &AvailFBArea); + xf86InitFBManager(pScreen, &AvailFBArea); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %i scanlines of offscreen memory \n" , lines - pScrn->virtualY); } @@ -1253,8 +1253,8 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) return FALSE; if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, - DUMMYLoadPalette, NULL, - CMAP_PALETTED_TRUECOLOR + DUMMYLoadPalette, NULL, + CMAP_PALETTED_TRUECOLOR | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; @@ -1292,7 +1292,7 @@ DUMMYSwitchMode(SWITCH_MODE_ARGS_DECL) DUMMYAdjustFrame(ADJUST_FRAME_ARGS_DECL) { SCRN_INFO_PTR(arg); - int Base; + int Base; Base = (y * pScrn->displayWidth + x) >> 2; @@ -1363,7 +1363,7 @@ DUMMYSaveScreen(ScreenPtr pScreen, int mode) dPtr = DUMMYPTR(pScrn); dPtr->screenSaver = xf86IsUnblank(mode); - } + } return TRUE; } @@ -1379,7 +1379,7 @@ dummySave(ScrnInfoPtr pScrn) { } - static void + static void dummyRestore(ScrnInfoPtr pScrn, Bool restoreText) { } @@ -1421,7 +1421,7 @@ DUMMYCreateWindow(WindowPtr pWin) VFB_PROP = MakeAtom(VFB_PROP_NAME, strlen(VFB_PROP_NAME), 1); #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 21 - ret = ChangeWindowProperty(pWinRoot, VFB_PROP, XA_STRING, + ret = ChangeWindowProperty(pWinRoot, VFB_PROP, XA_STRING, 8, PropModeReplace, (int)4, (pointer)"TRUE", FALSE); #else ret = dixChangeWindowProperty(serverClient, pWinRoot,