void setup(void) { ewmh_init(); screen = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data; if (!screen) die("error: cannot aquire screen\n"); screen_width = screen->width_in_pixels; screen_height = screen->height_in_pixels; root_depth = screen->root_depth; xcb_atom_t net_atoms[] = {ewmh->_NET_SUPPORTED, ewmh->_NET_DESKTOP_NAMES, ewmh->_NET_NUMBER_OF_DESKTOPS, ewmh->_NET_CURRENT_DESKTOP, ewmh->_NET_CLIENT_LIST, ewmh->_NET_ACTIVE_WINDOW, ewmh->_NET_WM_STATE, ewmh->_NET_WM_STATE_FULLSCREEN, ewmh->_NET_WM_WINDOW_TYPE, ewmh->_NET_WM_WINDOW_TYPE_DIALOG, ewmh->_NET_WM_WINDOW_TYPE_UTILITY, ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR}; xcb_ewmh_set_supported(ewmh, default_screen, LENGTH(net_atoms), net_atoms); desk = make_desktop(DEFAULT_DESK_NAME); last_desk = NULL; desk_head = desk; desk_tail = desk; num_desktops++; ewmh_update_number_of_desktops(); ewmh_update_desktop_names(); rule_head = make_rule(); frozen_pointer = make_pointer_state(); split_mode = MODE_AUTOMATIC; }
bool import_monitors(void) { PUTS("import monitors"); xcb_randr_get_screen_resources_current_reply_t *sres = xcb_randr_get_screen_resources_current_reply(dpy, xcb_randr_get_screen_resources_current(dpy, root), NULL); if (sres == NULL) return false; monitor_t *m, *mm = NULL; int len = xcb_randr_get_screen_resources_current_outputs_length(sres); xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(sres); xcb_randr_get_output_info_cookie_t cookies[len]; for (int i = 0; i < len; i++) cookies[i] = xcb_randr_get_output_info(dpy, outputs[i], XCB_CURRENT_TIME); for (m = mon_head; m != NULL; m = m->next) m->wired = false; for (int i = 0; i < len; i++) { xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(dpy, cookies[i], NULL); if (info != NULL) { if (info->crtc != XCB_NONE) { xcb_randr_get_crtc_info_reply_t *cir = xcb_randr_get_crtc_info_reply(dpy, xcb_randr_get_crtc_info(dpy, info->crtc, XCB_CURRENT_TIME), NULL); if (cir != NULL) { xcb_rectangle_t rect = (xcb_rectangle_t) {cir->x, cir->y, cir->width, cir->height}; mm = get_monitor_by_id(outputs[i]); if (mm != NULL) { mm->rectangle = rect; update_root(mm); for (desktop_t *d = mm->desk_head; d != NULL; d = d->next) for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) translate_client(mm, mm, n->client); arrange(mm, mm->desk); mm->wired = true; PRINTF("update monitor %s (0x%X)\n", mm->name, mm->id); } else { mm = add_monitor(rect); char *name = (char *)xcb_randr_get_output_info_name(info); size_t name_len = MIN(sizeof(mm->name), (size_t)xcb_randr_get_output_info_name_length(info) + 1); snprintf(mm->name, name_len, "%s", name); mm->id = outputs[i]; PRINTF("add monitor %s (0x%X)\n", mm->name, mm->id); } } free(cir); } else if (!remove_disabled_monitor && info->connection != XCB_RANDR_CONNECTION_DISCONNECTED) { m = get_monitor_by_id(outputs[i]); if (m != NULL) m->wired = true; } } free(info); } /* initially focus the primary monitor and add the first desktop to it */ xcb_randr_get_output_primary_reply_t *gpo = xcb_randr_get_output_primary_reply(dpy, xcb_randr_get_output_primary(dpy, root), NULL); if (gpo != NULL) { pri_mon = get_monitor_by_id(gpo->output); if (!running && pri_mon != NULL) { if (mon != pri_mon) mon = pri_mon; add_desktop(pri_mon, make_desktop(NULL)); ewmh_update_current_desktop(); } } free(gpo); /* handle overlapping monitors */ m = mon_head; while (m != NULL) { monitor_t *next = m->next; if (m->wired) { for (monitor_t *mb = mon_head; mb != NULL; mb = mb->next) if (mb != m && mb->wired && (m->desk == NULL || mb->desk == NULL) && contains(mb->rectangle, m->rectangle)) { if (mm == m) mm = mb; merge_monitors(m, mb); remove_monitor(m); break; } } m = next; } /* merge and remove disconnected monitors */ m = mon_head; while (m != NULL) { monitor_t *next = m->next; if (!m->wired) { merge_monitors(m, mm); remove_monitor(m); } m = next; } /* add one desktop to each new monitor */ for (m = mon_head; m != NULL; m = m->next) if (m->desk == NULL && (running || pri_mon == NULL || m != pri_mon)) add_desktop(m, make_desktop(NULL)); free(sres); update_motion_recorder(); return (num_monitors > 0); }
bool update_monitors(void) { xcb_randr_get_screen_resources_reply_t *sres = xcb_randr_get_screen_resources_reply(dpy, xcb_randr_get_screen_resources(dpy, root), NULL); if (sres == NULL) { return false; } monitor_t *m, *mm = NULL; int len = xcb_randr_get_screen_resources_outputs_length(sres); xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(sres); xcb_randr_get_output_info_cookie_t cookies[len]; for (int i = 0; i < len; i++) { cookies[i] = xcb_randr_get_output_info(dpy, outputs[i], XCB_CURRENT_TIME); } for (m = mon_head; m != NULL; m = m->next) { m->wired = false; } for (int i = 0; i < len; i++) { xcb_randr_get_output_info_reply_t *info = xcb_randr_get_output_info_reply(dpy, cookies[i], NULL); if (info != NULL) { if (info->crtc != XCB_NONE) { xcb_randr_get_crtc_info_reply_t *cir = xcb_randr_get_crtc_info_reply(dpy, xcb_randr_get_crtc_info(dpy, info->crtc, XCB_CURRENT_TIME), NULL); if (cir != NULL) { xcb_rectangle_t rect = (xcb_rectangle_t) {cir->x, cir->y, cir->width, cir->height}; mm = get_monitor_by_randr_id(outputs[i]); if (mm != NULL) { update_root(mm, &rect); mm->wired = true; } else { mm = make_monitor(&rect, XCB_NONE); char *name = (char *)xcb_randr_get_output_info_name(info); int len = xcb_randr_get_output_info_name_length(info); size_t name_size = MIN(sizeof(mm->name), (size_t) len + 1); snprintf(mm->name, name_size, "%s", name); mm->randr_id = outputs[i]; add_monitor(mm); } } free(cir); } else if (!remove_disabled_monitors && info->connection != XCB_RANDR_CONNECTION_DISCONNECTED) { m = get_monitor_by_randr_id(outputs[i]); if (m != NULL) { m->wired = true; } } } free(info); } xcb_randr_get_output_primary_reply_t *gpo = xcb_randr_get_output_primary_reply(dpy, xcb_randr_get_output_primary(dpy, root), NULL); if (gpo != NULL) { pri_mon = get_monitor_by_randr_id(gpo->output); } free(gpo); /* handle overlapping monitors */ if (merge_overlapping_monitors) { m = mon_head; while (m != NULL) { monitor_t *next = m->next; if (m->wired) { monitor_t *mb = mon_head; while (mb != NULL) { monitor_t *mb_next = mb->next; if (m != mb && mb->wired && contains(m->rectangle, mb->rectangle)) { if (mm == mb) { mm = m; } if (next == mb) { next = mb_next; } merge_monitors(mb, m); remove_monitor(mb); } mb = mb_next; } } m = next; } } /* merge and remove disconnected monitors */ if (remove_unplugged_monitors) { m = mon_head; while (m != NULL) { monitor_t *next = m->next; if (!m->wired) { merge_monitors(m, mm); remove_monitor(m); } m = next; } } /* add one desktop to each new monitor */ for (m = mon_head; m != NULL; m = m->next) { if (m->desk == NULL) { add_desktop(m, make_desktop(NULL, XCB_NONE)); } } if (!running && mon != NULL) { if (pri_mon != NULL) { mon = pri_mon; } center_pointer(mon->rectangle); ewmh_update_current_desktop(); } free(sres); return (mon != NULL); }
/* ** make_mac_volume: "create" an HFS volume using the ISO data ** ** The HFS volume structures are set up (but no data is written yet). ** ** ISO volumes have a allocation size of 2048 bytes - regardless ** of the size of the volume. HFS allocation size is depends on volume ** size, so we may have to update the ISO structures to add in any ** padding. */ int FDECL2(make_mac_volume, struct directory *, dpnt, int, start_extent) { char vol_name[HFS_MAX_VLEN+1]; /* Mac volume name */ hfsvol *vol; /* Mac volume */ int vlen, vblen; /* vol length (bytes, blocks) */ int Csize, lastCsize; /* allocation sizes */ int ret = 0; /* return value */ int loop = 1; /* umount volume if we have had a previous attempt */ if (vol_save) if (hfs_umount(vol_save, 0) < 0) return (-1); /* set the default clump size to the ISO block size */ lastCsize = SECTOR_SIZE; if (verbose > 1) fprintf(stderr, "Creating HFS Volume info\n"); /* name or copy ISO volume name to Mac Volume name */ strncpy(vol_name, hfs_volume_id ? hfs_volume_id : volume_id, HFS_MAX_VLEN); vol_name[HFS_MAX_VLEN] = '\0'; /* get initial size of HFS volume (size of ISO volume) */ vblen = last_extent * BLK_CONV; /* add on size of extents/catalog file, but this may mean the allocation size will change, so loop round until the allocation size doesn't change */ while (loop) { hce->XTCsize = XClpSiz(vblen); vblen = get_vol_size(vblen); Csize = AlcSiz(vblen); if (Csize == lastCsize) { /* allocation size hasn't changed, so carry on */ loop = 0; } else { /* allocation size has changed, so update ISO volume size */ if ((vlen = get_adj_size(Csize)) < 0) { snprintf(hce->error, ERROR_SIZE, "too many files for HFS volume"); return (-1); } vlen += V_ROUND_UP(start_extent * SECTOR_SIZE, Csize); vblen = vlen / HFS_BLOCKSZ; lastCsize = Csize; } } /* set vlen to size in bytes */ /* vlen = hce->hfs_vol_size = vblen * HFS_BLOCKSZ; */ /* take off the label/map size */ vblen -= hce->hfs_map_size; vlen = hce->hfs_vol_size = vblen * HFS_BLOCKSZ; /* set the default allocation size for libhfs */ hce->Csize = Csize; /* format and mount the "volume" */ if (hfs_format(hce, 0, vol_name) < 0) { snprintf(hce->error, ERROR_SIZE, "can't HFS format %s",vol_name); return(-1); } /* update the ISO structures with new start extents and any padding required */ if (Csize != SECTOR_SIZE) { last_extent = adj_size(Csize, start_extent, hce->hfs_hdr_size + hce->hfs_map_size); adj_size_other(dpnt); } if ((vol = hfs_mount(hce, 0, 0)) == 0) { snprintf(hce->error, ERROR_SIZE, "can't HFS mount %s",vol_name); return(-1); } /* save the volume for possible later use */ vol_save = vol; /* Recursively "copy" the files to the volume - we need to know the first allocation block in the volume as starting blocks of files are relative to this. */ ret = copy_to_mac_vol(vol, dpnt); if (ret < 0) return(ret); /* make the Desktop files - I *think* this stops the Mac rebuilding the desktop when the CD is mounted on a Mac These will be ignored if they already exist */ if (create_dt) ret = make_desktop(vol, last_extent*BLK_CONV); if (ret < 0) return(ret); /* close the volume */ if (hfs_flush(vol) < 0) return(-1); /* unmount and set the start blocks for the catalog/extents files */ if (hfs_umount(vol, last_extent*BLK_CONV) < 0) return(-1); return(Csize); }