static void ins_level(int l, ENTRY *e) { int i; if ( l < 0) { for (i = 1; i < MAX_LEVELS; i++) { CO(MAX_LEVELS - i) = CO(MAX_LEVELS - i - 1); CB(MAX_LEVELS - i) = CB(MAX_LEVELS - i - 1); } memcpy(spare_block, &(pci->root), sizeof(BLOCK)); spare_block->brec = get_free(); write_if(pci->ixfile, spare_block->brec,(char *) spare_block, sizeof(BLOCK)); pci->root.p0 = spare_block->brec; copy_entry((ENTRY *) (pci->root.entries), e); pci->root.bend = ENT_SIZE(e); CO(0) = 0; pci->level = 0; (pci->dx.nl)++; update_root(&(pci->root)); } else { ins_block(block_ptr,e,CO(l)); } }
/* Update window's (x,y) co-ordinates */ static void geo_update(void) { if (!cur) update_root(); else update_sub_window(); }
static void del_block(BLOCK *pb, int off) { int ne; update_root(pb); ne = ENT_SIZE(ENT_ADR(pb, off)); movedown(pb, off, ne); pb->bend -= ne; }
static void ins_block(BLOCK *pb, ENTRY *pe, int off) { int size; update_root(pb); size = ENT_SIZE(pe); moveup(pb,off,size); copy_entry(ENT_ADR(pb,off),pe); pb->bend += size; }
monitor_t *make_monitor(xcb_rectangle_t *rect) { monitor_t *m = malloc(sizeof(monitor_t)); snprintf(m->name, sizeof(m->name), "%s%02d", DEFAULT_MON_NAME, ++monitor_uid); m->id = XCB_NONE; m->root = XCB_NONE; m->prev = m->next = NULL; m->desk = m->desk_head = m->desk_tail = NULL; m->top_padding = m->right_padding = m->bottom_padding = m->left_padding = 0; m->wired = true; m->sticky_count = 0; if (rect != NULL) { update_root(m, rect); } else { m->rectangle = (xcb_rectangle_t) {0, 0, screen_width, screen_height}; } return m; }
/* insert new entries into tree */ static bool split(int l, ENTRY *pe, ENTRY *e) { int half, ins_pos, size; ins_pos = CO(pci->level); half = scan_blk(block_ptr->bend / 2 + sizeof(RECPOS)); if (half == ins_pos) { *e = *pe; } else { copy_entry(e, ENT_ADR(block_ptr, half)); size = ENT_SIZE(e); movedown(block_ptr, half, size); block_ptr->bend -= size; update_root(block_ptr); } spare_block = &BUFBLOCK(new_cache()); memcpy(spare_block->entries, ENT_ADR(block_ptr,half), block_ptr->bend - half); spare_block->brec = get_free(); spare_block->bend = block_ptr->bend - half; spare_block->p0 = e->idxptr; block_ptr->bend = half; e->idxptr = spare_block->brec; if (ins_pos < half) { ins_block(block_ptr,pe,ins_pos); } else if (ins_pos > half) { ins_pos -= ENT_SIZE(e); ins_block(spare_block,pe,ins_pos - half); CB(l) = e->idxptr; CO(l) = CO(l) - half; } write_if(pci->ixfile, spare_block->brec,(char *) spare_block, sizeof(BLOCK)); return TRUE; }
monitor_t *make_monitor(xcb_rectangle_t *rect, uint32_t id) { monitor_t *m = malloc(sizeof(monitor_t)); if (id == XCB_NONE) { m->id = xcb_generate_id(dpy); } m->randr_id = XCB_NONE; snprintf(m->name, sizeof(m->name), "%s", DEFAULT_MON_NAME); m->padding = padding; m->border_width = border_width; m->window_gap = window_gap; m->root = XCB_NONE; m->prev = m->next = NULL; m->desk = m->desk_head = m->desk_tail = NULL; m->wired = true; m->sticky_count = 0; if (rect != NULL) { update_root(m, rect); } else { m->rectangle = (xcb_rectangle_t) {0, 0, screen_width, screen_height}; } return m; }
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); }
/* BPLUS delete key functions */ int delete_key(ENTRY *pe, IX_DESC *pix) { ENTRY e; RECPOS ads; int h, leveli, levelf; if (!find_exact(pe, pix)) { return (IX_NOTEXISTED); } h = 1; if ((ads = pe->idxptr) != NULLREC) { leveli = pci->level; do { retrieve_block(++(pci->level), ads); CO(pci->level) = -1; } while ((ads = block_ptr->p0) != NULLREC); CO(pci->level) = 0; copy_entry(&e, ENT_ADR(block_ptr, CO(pci->level))); levelf = pci->level; pci->level = leveli; replace_entry(&e); pci->level = levelf; /*update_root(&pci->root);*/ } while ( h ) { retrieve_block(pci->level, CB(pci->level)); del_block(block_ptr, CO(pci->level)); update_block(); if ( (pci->level == 0) && (block_ptr->bend == 0)) /* tree was reduced in height */ { if (pci->root.p0 != NULLREC) { retrieve_block(++pci->level, pci->root.p0); memcpy(&(pci->root), block_ptr, sizeof(BLOCK)); (pci->dx.nl)--; write_free(block_ptr->brec, block_ptr); BUFDIRTY(cache_ptr) = 0; BUFHANDLE(cache_ptr) = 0; update_root(&pci->root); } break; } h = (block_ptr->bend < comb_size) && (pci->level > 0); if ( h ) { h = combineblk(CB(pci->level), block_ptr->bend); } } /*return flush_index(pix);*/ if(root_dirty == 1) { flush_index(pix); root_dirty = 0; } return(IX_OK); }
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); }