/* * Replace a key/value pair in buffer. #{blah} is expanded directly, * #{?blah,a,b} is replace with a if blah exists and is nonzero else b. */ int format_replace(struct format_tree *ft, const char *key, size_t keylen, char **buf, size_t *len, size_t *off) { char *copy, *ptr; const char *value; size_t valuelen; /* Make a copy of the key. */ copy = xmalloc(keylen + 1); memcpy(copy, key, keylen); copy[keylen] = '\0'; /* * Is this a conditional? If so, check it exists and extract either the * first or second element. If not, look up the key directly. */ if (*copy == '?') { ptr = strchr(copy, ','); if (ptr == NULL) goto fail; *ptr = '\0'; value = format_find(ft, copy + 1); if (value != NULL && (value[0] != '0' || value[1] != '\0')) { value = ptr + 1; ptr = strchr(value, ','); if (ptr == NULL) goto fail; *ptr = '\0'; } else { ptr = strchr(ptr + 1, ','); if (ptr == NULL) goto fail; value = ptr + 1; } } else { value = format_find(ft, copy); if (value == NULL) value = ""; } valuelen = strlen(value); /* Expand the buffer and copy in the value. */ while (*len - *off < valuelen + 1) { *buf = xrealloc(*buf, 2, *len); *len *= 2; } memcpy(*buf + *off, value, valuelen); *off += valuelen; xfree(copy); return (0); fail: xfree(copy); return (-1); }
static VALUE ruby_format_find(int argc, VALUE *argv, VALUE self) { if (argc != 1) rb_raise(rb_eArgError, "format_find() accepts 1 param, but %d given", argc); Check_Type(argv[0], T_STRING); return rb_str_new2(format_find(RSTRING(argv[0])->ptr)); // return ekg2_ruby_theme; }
/* we return 0 even if rmwatch fails, because xmsg_handle_data checks * if our session is still connected, so it'll ignore unneeded events */ static COMMAND(xmsg_disconnect) { if (!session_connected_get(session)) { printq("not_connected", session_name(session)); return -1; } xmsg_timer_change(session, NULL); if (!timer_remove_session(session, "o")) xdebug("old oneshot resume timer removed"); session_status_set(session, EKG_STATUS_NA); if (quiet == -1) protocol_disconnected_emit(session, format_find("xmsg_umount"), EKG_DISCONNECT_NETWORK); else protocol_disconnected_emit(session, NULL, EKG_DISCONNECT_USER); #ifdef HAVE_INOTIFY if (session->priv && inotify_rm_watch(in_fd, (long int) session->priv)) xdebug2(DEBUG_ERROR, "rmwatch failed"); else xdebug("inotify watch removed: %d", (long int) session->priv); #endif /*HAVE_INOTIFY*/ return 0; }
/** * current_prompt() * * Get the current prompt, locale-recoded. * * @return Static buffer pointer, non-NULL, locale-encoded. */ const /*locale*/ char *current_prompt(void) { static gchar *buf = NULL; session_t *s; char *tmp, *act, *sid; char *format, *format_act; if (no_prompt) return ""; s = session_current; sid = s ? (s->alias?s->alias:s->uid) : ""; if (window_current->id > 1) { format = "rl_prompt_query"; format_act = "rl_prompt_query_act"; } else if (s && (s && s->status == EKG_STATUS_INVISIBLE)) { format = "rl_prompt_invisible"; format_act = "rl_prompt_invisible_act"; } else if (s && (s->status < EKG_STATUS_AVAIL)) { format = "rl_prompt_away"; format_act = "rl_prompt_away_act"; } else { format = "rl_prompt"; format_act = "rl_prompt_act"; } act = window_activity(); if (act) tmp = format_string(format_find(format_act), sid, ekg_itoa(window_current->id), act, window_current->target); else tmp = format_string(format_find(format), sid, ekg_itoa(window_current->id), window_current->target); g_free(buf); buf = ekg_recode_to_locale(tmp); g_free(tmp); g_free(act); return buf; }
static COMMAND(xmsg_connect) { if (session_connected_get(session)) { printq("already_connected", session_name(session)); return -1; } if (command_exec(NULL, session, "/session --lock", 0) == -1) return -1; if (xmsg_add_watch(session, session_uid_get(session)+XMSG_UID_DIROFFSET)) { print("conn_failed", format_find("xmsg_addwatch_failed"), session_name(session)); return -1; } session_status_set(session, EKG_STATUS_AVAIL); protocol_connected_emit(session); xmsg_iterate_dir(0, (void*) session); xmsg_timer_change(session, "rescan_timer"); return 0; }
/* * Replace a key/value pair in buffer. #{blah} is expanded directly, * #{?blah,a,b} is replace with a if blah exists and is nonzero else b. */ int format_replace(struct format_tree *ft, const char *key, size_t keylen, char **buf, size_t *len, size_t *off) { char *copy, *copy0, *endptr, *ptr, *saved; const char *value; size_t valuelen; u_long limit = ULONG_MAX; /* Make a copy of the key. */ copy0 = copy = xmalloc(keylen + 1); memcpy(copy, key, keylen); copy[keylen] = '\0'; /* Is there a length limit or whatnot? */ if (!islower((u_char) *copy) && *copy != '?') { while (*copy != ':' && *copy != '\0') { switch (*copy) { case '=': errno = 0; limit = strtoul(copy + 1, &endptr, 10); if (errno == ERANGE && limit == ULONG_MAX) goto fail; copy = endptr; break; default: copy++; break; } } if (*copy != ':') goto fail; copy++; } /* * Is this a conditional? If so, check it exists and extract either the * first or second element. If not, look up the key directly. */ if (*copy == '?') { ptr = strchr(copy, ','); if (ptr == NULL) goto fail; *ptr = '\0'; value = format_find(ft, copy + 1); if (value != NULL && (value[0] != '0' || value[1] != '\0')) { value = ptr + 1; ptr = strchr(value, ','); if (ptr == NULL) goto fail; *ptr = '\0'; } else { ptr = strchr(ptr + 1, ','); if (ptr == NULL) goto fail; value = ptr + 1; } saved = format_expand(ft, value); value = saved; } else { value = format_find(ft, copy); if (value == NULL) value = ""; saved = NULL; } valuelen = strlen(value); /* Truncate the value if needed. */ if (valuelen > limit) valuelen = limit; /* Expand the buffer and copy in the value. */ while (*len - *off < valuelen + 1) { *buf = xrealloc(*buf, 2, *len); *len *= 2; } memcpy(*buf + *off, value, valuelen); *off += valuelen; free(saved); free(copy0); return (0); fail: free(copy0); return (-1); }
/* * ncurses_contacts_update() * * updates contacts window * * it switches also groups, metacontacts, all together * details in documentation * */ int ncurses_contacts_update(window_t *w, int save_pos) { int old_start; const char *header = NULL, *footer = NULL; char *group = NULL; int j; int all = 0; /* 1 - all, 2 - metacontacts */ ncurses_window_t *n; newconference_t *c = NULL; userlist_t *sorted_all = NULL; int (*comp)(void *, void *) = NULL; /* coz userlist's list are sorted we don't need to sort it again... unfortunetly if we create list from serveral userlists (for instance: session && window) we must resort... --- in ekg2 we do list_add_sorted(...., NULL) on session userlist && list_add_sorted(...., contacts_compare) on window userlist */ if (!w) w = window_find_sa(NULL, "__contacts", 1); if (!w) return -1; n = w->priv_data; if (save_pos) old_start = n->start; else old_start = 0; ncurses_clear(w, 1); if (!session_current) goto kon; if (config_contacts_groups) { char **groups = array_make(config_contacts_groups, ", ", 0, 1, 0); int count = array_count(groups); if (contacts_group_index > count + 2) { contacts_group_index = 0; } else if (contacts_group_index > count + 1) { if (metacontacts) all = 2; else contacts_group_index = 0; } else if (contacts_group_index > count) { all = 1; } else if (contacts_group_index > 0) { all = config_contacts_groups_all_sessions ? 1 : 0; group = groups[contacts_group_index - 1]; if (*group == '@') group++; group = xstrdup(group); header = format_find("contacts_header_group"); footer = format_find("contacts_footer_group"); } array_free(groups); } else if (contacts_group_index) { if (contacts_group_index > ((metacontacts) ? 2 :1) ) contacts_group_index = 0; else all = contacts_group_index; } if (all == 2) { header = format_find("contacts_metacontacts_header"); footer = format_find("contacts_metacontacts_footer"); } c = newconference_find(window_current->session, window_current->target); if (!session_current->userlist && !window_current->userlist && (!c || !c->participants) && !all && contacts_group_index == 0) goto kon; if (!header || !footer) { header = format_find("contacts_header"); footer = format_find("contacts_footer"); } if (format_ok(header)) ncurses_backlog_add(w, fstring_new_format(header, group)); if (all == 1) { userlist_t *l; session_t *s; for (s = sessions; s; s = s->next) { userlist_t *lp; if (!s->userlist) continue; for (lp = s->userlist; lp; lp = lp->next) { userlist_t *u = lp; if (!u->nickname) /* don't add users without nickname.. */ continue; LIST_ADD_SORTED2(&sorted_all, userlist_dup(u, u->uid, u->nickname, s), comp); } comp = contacts_compare; /* turn on sorting */ } for (l = c ? c->participants : window_current->userlist; l; l = l->next) { userlist_t *u = l; if (!u->nickname) /* don't add users without nickname.. */ continue; LIST_ADD_SORTED2(&sorted_all, userlist_dup(u, u->uid, u->nickname, w->session), comp); } if (sorted_all) comp = contacts_compare; /* like above */ } if (all == 1 || all == 2) { metacontact_t *m; /* Remove contacts contained in metacontacts. */ if (all == 1 && config_contacts_metacontacts_swallow) { for (m = metacontacts; m; m = m->next) { metacontact_item_t *i; /* metacontact_find_prio() should always success [for current API] */ /* if (!metacontact_find_prio(m)) continue; */ for (i = m->metacontact_items; i; i = i->next) { userlist_t *u; userlist_t *sl; if (!(u = userlist_find_n(i->s_uid, i->name))) continue; for (sl = sorted_all; sl;) { userlist_t *up = sl; userlist_t *next = sl->next;; /* up->uid == u->uid (?) */ if (up->uid && !xstrcmp(up->uid, u->uid)) LIST_REMOVE2(&sorted_all, up, NULL); sl = next; } } } } for (m = metacontacts; m; m = m->next) { metacontact_item_t *i; userlist_t *u; if (!(i = metacontact_find_prio(m))) continue; if (!(u = userlist_find_n(i->s_uid, i->name))) continue; if (!m->name) /* don't add metacontacts without name.. */ continue; LIST_ADD_SORTED2(&sorted_all, userlist_dup(u, NULL, m->name, (void *) 2), comp); } } if (!all) { sorted_all = session_current->userlist; if (c && c->participants) sorted_all = c->participants; else if (window_current->userlist) sorted_all = window_current->userlist; } if (!sorted_all) goto after_loop; /* it skips this loop below */ for (j = 0; j < corderlen; /* xstrlen(contacts_order); */ j += 2) { const char *footer_status = NULL; int count = 0; char tmp[100]; userlist_t *ul; for (ul = sorted_all; ul; ul = ul->next) { userlist_t *u = ul; const char *status_t; const char *format; fstring_t *string; if (!u->nickname || !u->status) continue; status_t = ekg_status_string(u->status, 0); if (config_contacts_orderbystate ? xstrncmp(contacts_order + j, status_t, 2) : /* when config_contacts_orderbystate, we need to have got this status in contacts_order now. */ !xstrstr(contacts_order, get_short_status(status_t))) /* when !config_contacts_orderbystate, we need to have got this status in contacts_order anywhere. */ continue; if (group && (!u->priv_data || (void *) 2 != u->priv_data)) { userlist_t *tmp = userlist_find(u->priv_data ? u->priv_data : session_current, u->uid); if ((group[0]=='!' && ekg_group_member(tmp, group+1)) || (group[0]!='!' && !ekg_group_member(tmp, group))) continue; } if (!count) { snprintf(tmp, sizeof(tmp), "contacts_%s_header", status_t); format = format_find(tmp); if (format_ok(format)) ncurses_backlog_add(w, fstring_new_format(format)); footer_status = status_t; } if (u->descr && config_contacts_descr) snprintf(tmp, sizeof(tmp), "contacts_%s_descr_full", status_t); else if (u->descr && !config_contacts_descr) snprintf(tmp, sizeof(tmp), "contacts_%s_descr", status_t); else snprintf(tmp, sizeof(tmp), "contacts_%s", status_t); if (u->blink) xstrcat(tmp, "_blink"); if (u->typing) xstrcat(tmp, "_typing"); string = fstring_new_format(format_find(tmp), u->nickname, u->descr); if (u->priv_data == (void *) 2) string->priv_data = (void *) xstrdup(u->nickname); else string->priv_data = (void *) saprintf("%s/%s", (u->priv_data) ? ((session_t *) u->priv_data)->uid : session_current->uid, u->nickname); ncurses_backlog_add(w, string); count++; } if (count) { const char *format; snprintf(tmp, sizeof(tmp), "contacts_%s_footer", footer_status); format = format_find(tmp); if (format_ok(format)) ncurses_backlog_add(w, fstring_new_format(format)); } if (!config_contacts_orderbystate) break; } after_loop: if (format_ok(footer)) ncurses_backlog_add(w, fstring_new_format(footer, group)); if (all) LIST_DESTROY2(sorted_all, NULL); xfree(group); kon: /* restore old index */ n->start = old_start; if (n->start > n->lines_count - w->height + n->overflow) n->start = n->lines_count - w->height + n->overflow; if (n->start < 0) n->start = 0; /* redraw */ n->redraw = 1; ncurses_redraw(w); return -1; }
static int icq_snac_extension_userfound_common(session_t *s, unsigned char *buf, int len, int islast) { char *nickname = NULL; char *first_name = NULL; char *last_name = NULL; char *email = NULL; char *full_name; char *temp; const char *__age = NULL; const char *__gender = ""; char *__active; uint32_t uin; uint16_t len2; uint16_t status, age; uint8_t auth, gender; /* XXX, sprawdzic czy mamy cookie. */ if (!ICQ_UNPACK(&buf, "w", &len2)) return -1; if (len < len2) return -1; if (!ICQ_UNPACK(&buf, "i", &uin)) return -1; if (!ICQ_UNPACK(&buf, "S", &temp)) goto cleanup; nickname = xstrdup(temp); if (!ICQ_UNPACK(&buf, "S", &temp)) goto cleanup; first_name = xstrdup(temp); if (!ICQ_UNPACK(&buf, "S", &temp)) goto cleanup; last_name = xstrdup(temp); if (!ICQ_UNPACK(&buf, "S", &temp)) goto cleanup; email = xstrdup(temp); if (first_name[0] && last_name[0]) full_name = saprintf("%s %s", first_name, last_name); else full_name = xstrdup(first_name[0] ? first_name : last_name); if (ICQ_UNPACK(&buf, "cwcw", &auth, &status, &gender, &age)) { if (age) __age = itoa(age); // XXX calculate birthyear? if (gender) __gender = (gender==2) ? "m" : "f"; } else { debug_error("icq_snac_extension_userfound_common() broken\n"); auth = status = gender = age = 0; } /* XXX, "search_results_multi", "search_results_single" */ /* XXX, instead of email we had city */ /* XXX, some time ago i was thinking to of function which * if data was truncated [because of width in format] * it'd take another line to complete.. * * i don't like truncation of data for instance: * 08:17:12 97320776 | darkjames | Jakub Zawadz | - | darkjames@po * * i was thinking about: * 97320776 | darkjames | Jakub Zawwdz | - | darkjames@po * ki czta.onet.pl * * of course we can do more magic, and wrap... * Jakub * Zawadzki * * or maybe let's align to center? :) * Jakub * Zawadzki */ { const char *fvalue; /* XXX ?wo? new formats for icq status * status (0 - offline, 1 - online, 2 - non_webaware) */ switch (status) { case 0: fvalue = format_find("search_results_multi_notavail"); break; case 1: fvalue = format_find("search_results_multi_avail"); break; default: fvalue = format_find("search_results_multi_unknown"); break; } temp = format_string(fvalue); /* XXX ?wo? add format for "auth" */ __active = saprintf("%s %s", temp, auth ? " " : "A"); xfree(temp); } print_info(NULL, s, "search_results_multi", itoa(uin), full_name, nickname, email, __age ? __age : ("-"), __gender, __active); xfree(__active); xfree(full_name); if (islast && len>=4) { uint32_t omit; ICQ_UNPACK(&buf, "I", &omit); debug_warn("icq_snac_extension_userfound_last() Bulshit warning!\n"); debug_white("icq_snac_extension_userfound_last() %d search results omitted\n", omit); } icq_hexdump(DEBUG_WHITE, buf, len); xfree(nickname); xfree(first_name); xfree(last_name); xfree(email); return 0; cleanup: xfree(nickname); xfree(first_name); xfree(last_name); xfree(email); return -1; }
/* * ui_readline_print() * * wy¶wietla dany tekst na ekranie, uwa¿aj±c na trwaj±ce w danych chwili * readline(). */ void ui_readline_print(window_t *w, int separate, const /*locale*/ char *xline) { int old_end = rl_end, id = w->id; char *old_prompt = NULL, *line_buf = NULL; const char *line = NULL; if (config_timestamp) { /* XXX: recode timestamp? for fun or wcs? */ string_t s = string_init(NULL); const char *p = xline; const char *buf = timestamp(formated_config_timestamp); string_append(s, "\033[0m"); string_append(s, buf); string_append_c(s, ' '); while (*p) { string_append_c(s, *p); if (*p == '\n' && *(p + 1)) { string_append(s, buf); string_append_c(s, ' '); } p++; } line = line_buf = string_free(s, 0); } else line = xline; /* je¶li nie piszemy do aktualnego, to zapisz do bufora i wyjd¼ */ if (id != window_current->id) { window_write(id, line); /* XXX trzeba jeszcze waln±æ od¶wie¿enie prompta */ goto done; } /* je¶li mamy ukrywaæ wszystko, wychodzimy */ if (pager_lines == -2) goto done; window_write(window_current->id, line); /* ukryj prompt, je¶li jeste¶my w trakcie readline */ if (in_readline) { old_prompt = g_strdup(rl_prompt); rl_end = 0; /* set_prompt(NULL);*/ rl_redisplay(); /* XXX: string width instead? * or cleartoeol? */ printf("\r%*c\r", (int) xstrlen(old_prompt), ' '); } printf("%s", line); if (pager_lines >= 0) { pager_lines++; if (pager_lines >= screen_lines - 2) { const gchar *prompt = format_find("readline_more"); char *lprompt = ekg_recode_to_locale(prompt); char *tmp; /* XXX: lprompt pretty const, make it static? */ in_readline++; set_prompt(lprompt); pager_lines = -1; tmp = readline(lprompt); g_free(lprompt); in_readline--; if (tmp) { free(tmp); /* allocd by readline */ pager_lines = 0; } else { printf("\n"); pager_lines = -2; } printf("\033[A\033[K"); /* XXX brzydko */ } } /* je¶li jeste¶my w readline, poka¿ z powrotem prompt */ if (in_readline) { rl_end = old_end; set_prompt(old_prompt); g_free(old_prompt); rl_forced_update_display(); } done: if (line_buf) g_free(line_buf); }
/* * gg_session_handler_search50() * * zajmuje siê obs³ug± wyniku przeszukiwania katalogu publicznego. * * - s - sesja * - e - opis zdarzenia */ void gg_session_handler_search50(session_t *s, struct gg_event *e) { gg_private_t *g = session_private_get(s); gg_pubdir50_t res = e->event.pubdir50; int i, count, all = 0; list_t l; uin_t last_uin = 0; if (!g) return; if ((count = gg_pubdir50_count(res)) < 1) { print("search_not_found"); return; } debug_function("gg_session_handler_search50() handle_search50, count = %d\n", gg_pubdir50_count(res)); for (l = g->searches; l; l = l->next) { gg_pubdir50_t req = l->data; if (gg_pubdir50_seq(req) == gg_pubdir50_seq(res)) { all = 1; break; } } for (i = 0; i < count; i++) { const char *uin = gg_pubdir50_get(res, i, "fmnumber"); const char *__firstname = gg_pubdir50_get(res, i, "firstname"); const char *__lastname = gg_pubdir50_get(res, i, "lastname"); const char *__nickname = gg_pubdir50_get(res, i, "nickname"); const char *__fmstatus = gg_pubdir50_get(res, i, "fmstatus"); const char *__birthyear = gg_pubdir50_get(res, i, "birthyear"); const char *__city = gg_pubdir50_get(res, i, "city"); char *firstname = gg_to_core_dup(s, __firstname); char *lastname = gg_to_core_dup(s, __lastname); char *nickname = gg_to_core_dup(s, __nickname); char *city = gg_to_core_dup(s, __city); int status = (__fmstatus) ? atoi(__fmstatus) : GG_STATUS_NOT_AVAIL; const char *birthyear = (__birthyear && xstrcmp(__birthyear, "0")) ? __birthyear : NULL; char *name, *active, *gender; const char *target = NULL; if (count == 1 && !all) { xfree(last_search_first_name); xfree(last_search_last_name); xfree(last_search_nickname); xfree(last_search_uid); last_search_first_name = xstrdup(firstname); last_search_last_name = xstrdup(lastname); last_search_nickname = xstrdup(nickname); last_search_uid = saprintf("gg:%s", uin); } name = saprintf( ("%s %s"), firstname ? firstname : (""), lastname ? lastname : ("")); #define __format(x) ((count == 1 && !all) ? "search_results_single" x : "search_results_multi" x) { const char *fvalue; switch (status) { case GG_STATUS_AVAIL: case GG_STATUS_AVAIL_DESCR: fvalue = format_find(__format("_avail")); break; case GG_STATUS_BUSY: case GG_STATUS_BUSY_DESCR: fvalue = format_find(__format("_away")); break; default: fvalue = format_find(__format("_notavail")); } active = format_string(fvalue, (__firstname) ? __firstname : nickname); } gender = format_string(format_find(__format("_unknown")), ""); /* XXX: why do we _exactly_ use it here? can't we just always * define target and thus display result in right conversation window? */ for (l = autofinds; l; l = l->next) { char *d = (char *) l->data; if (!xstrcasecmp(d + 3, uin)) { target = d; break; } } print_info(target, s, __format(""), uin ? uin : ("?"), name, nickname ? nickname : (""), city ? city : (""), birthyear ? birthyear : ("-"), gender, active); #undef __format xfree(name); xfree(active); xfree(gender); xfree(firstname); xfree(lastname); xfree(nickname); xfree(city); last_uin = atoi(uin); } /* je¶li mieli¶my ,,/find --all'', szukamy dalej */ for (l = g->searches; l; l = l->next) { gg_pubdir50_t req = l->data; uin_t next; if (gg_pubdir50_seq(req) != gg_pubdir50_seq(res)) continue; /* nie ma dalszych? to dziêkujemy */ if (!(next = gg_pubdir50_next(res)) || !g->sess || next <= last_uin) { list_remove(&g->searches, req, 0); gg_pubdir50_free(req); break; } gg_pubdir50_add(req, GG_PUBDIR50_START, ekg_itoa(next)); gg_pubdir50(g->sess, req); break; } }
/* * variable_help() * * wy¶wietla pomoc dotycz±c± danej zmiennej na podstawie pliku * ${datadir}/ekg/vars.txt. * * - name - nazwa zmiennej. */ void variable_help(const char *name) { FILE *f = fopen(DATADIR "/vars.txt", "r"); char *line, *type = NULL, *def = NULL, *tmp; string_t s = string_init(NULL); int found = 0; if (!f) { print("help_set_file_not_found"); return; } while ((line = read_file(f))) { if (strlen(line) >= 2 && line[0] == '/' && line[1] == '/') { xfree(line); continue; } if (!strcasecmp(line, name)) { found = 1; xfree(line); break; } xfree(line); } if (!found) { fclose(f); print("help_set_var_not_found", name); return; } line = read_file(f); if ((tmp = strstr(line, ": "))) type = xstrdup(tmp + 2); else type = xstrdup("?"); xfree(line); tmp = NULL; line = read_file(f); if ((tmp = strstr(line, ": "))) def = xstrdup(tmp + 2); else def = xstrdup("?"); xfree(line); print("help_set_header", name, type, def); xfree(type); xfree(def); if (tmp) /* je¶li nie jest to ukryta zmienna... */ xfree(read_file(f)); /* ... pomijamy liniê */ while ((line = read_file(f))) { if (line[0] != '\t') { xfree(line); break; } if (!strncmp(line, "\t- ", 3) && strcmp(s->str, "")) { print("help_set_body", s->str); string_clear(s); } string_append(s, line + 1); if (line[strlen(line) - 1] != ' ') string_append_c(s, ' '); xfree(line); } if (strcmp(s->str, "")) print("help_set_body", s->str); string_free(s, 1); if (strcmp(format_find("help_set_footer"), "")) print("help_set_footer", name); fclose(f); }
/* * wyswietla ponownie linie wprowadzenia tekstu (prompt + aktualnie wpisany tekst) * przy okazji jesli jest aspell to sprawdza czy tekst jest poprawny. */ void ncurses_redraw_input(unsigned int ch) { int x, y; /* draw prompt */ werase(input); wmove(input, 0, 0); if (!ncurses_lines) { gchar *tmp = ekg_recode_to_locale(format_find( ncurses_current->prompt ? "ncurses_prompt_query" : "ncurses_prompt_none")); gchar *tmp2 = format_string(tmp, "\037"); /* unit separator */ fstring_t *prompt_f = fstring_new(tmp2); gchar *s = prompt_f->str, *s2; fstr_attr_t *a = prompt_f->attr, *a2; g_free(tmp2); g_free(tmp); if (ncurses_current->prompt) { /* find our \037 */ for (s2 = s, a2 = a; *s2 != '\037'; s2++, a2++) g_assert(*s2); *s2 = '\0'; /* and split the original string using it */ } ncurses_fstring_print(input, s, a, -1); if (ncurses_current->prompt) { if (!ncurses_simple_print(input, ncurses_current->prompt, *a2, input->_maxx / 4)) { /* don't change colors or anything * just disable bold to distinguish */ wattroff(input, A_BOLD); /* XXX? */ waddstr(input, ncurses_hellip); } s2++, a2++; ncurses_fstring_print(input, s2, a2, -1); } fstring_free(prompt_f); } getyx(input, y, x); ncurses_current->prompt_len = x; /* XXX: cleanup, optimize */ { int cur_posx = -1, cur_posy = 0; const int width = input->_maxx - x; if ((line_index - line_start >= width) || (line_index - line_start < 2)) line_start = line_index - width/2; if (line_start < 0) line_start = 0; ncurses_redraw_input_already_exec = 1; wattrset(input, color_pair(COLOR_WHITE, COLOR_BLACK)); if (ncurses_lines) { int i, x; cur_posy = lines_index - lines_start; for (i = 0; i < MULTILINE_INPUT_SIZE; i++) { if (!ncurses_lines[lines_start + i]) break; wmove(input, i, 0); x = ncurses_redraw_input_line(ncurses_lines[lines_start + i]); if (lines_index == (lines_start + i)) cur_posx = x; } wattrset(input, color_pair(COLOR_BLACK, COLOR_BLACK) | A_BOLD); if (lines_start>0) mvwaddch(input, 0, input->_maxx, '^'); if (g_strv_length((char **) ncurses_lines)-lines_start > MULTILINE_INPUT_SIZE) mvwaddch(input, MULTILINE_INPUT_SIZE-1, input->_maxx, 'v'); wattrset(input, A_NORMAL); } else { #if 0 if (ncurses_noecho) { static char *funnything = ncurses_funnything; waddch(input, ' '); /* XXX why here? If you want to add space after propt, add it in theme */ waddch(input, *funnything); wmove(input, 0, getcurx(input)-1); if (!*(++funnything)) funnything = ncurses_funnything; return; } #endif cur_posx = ncurses_redraw_input_line(ncurses_line); } /* this mut be here if we don't want 'timeout' after pressing ^C */ if (ch == 3) ncurses_commit(); if (cur_posx != -1) { wmove(input, cur_posy, cur_posx); curs_set(1); } else { wmove(input, 0, 0); // XXX ??? curs_set(0); } } }