| tvkaista-0.975/custom-list.c | | tvkaista-0.976/custom-list.c |
| 6 | WARN="$WARN -W -Wwrite-strings -Wcast-qual -Wshadow" # -Wconversion | 6 | WARN="$WARN -W -Wwrite-strings -Wcast-qual -Wshadow" # -Wconversion |
| 7 | FLAGS=`pkg-config --cflags --libs gtk+-2.0 | sed 's/-I/-isystem '/g` | 7 | FLAGS=`pkg-config --cflags --libs gtk+-2.0 | sed 's/-I/-isystem '/g` |
| 8 | ver=`sed -n 's/Version=//p' tvkaista.desktop` | 8 | ver=`sed -n 's/Version=//p' tvkaista.desktop` |
| 9 | OPTS="$WARN $FLAGS -DVERSION=$ver" | 9 | OPTS="$WARN $FLAGS -DVERSION=$ver -fstack-protector" |
| 10 | case $1 in '') set x -ggdb | 10 | case $1 in '') set x -ggdb |
| 11 | #case $1 in '') set x -O2 ### set x -ggdb | 11 | #case $1 in '') set x -O2 ### set x -ggdb |
| 12 | shift ;; esac; | 12 | shift ;; esac; |
| 16 | */ | 16 | */ |
| 17 | #endif | 17 | #endif |
| 18 | | 18 | |
| 19 | | | |
| 20 | /* original from http://scentric.net/tutorial/sec-custom-model-code.html */ | 19 | /* original from http://scentric.net/tutorial/sec-custom-model-code.html */ |
| 21 | /* ** part of GTK+ 2.0 Tree View Tutorial ** */ | 20 | /* ** part of GTK+ 2.0 Tree View Tutorial ** */ |
| 22 | | 21 | |
| | 22 | #define _GNU_SOURCE |
| 23 | #include <string.h> | 23 | #include <string.h> |
| 24 | #include <stdlib.h> | 24 | #include <stdlib.h> |
| 25 | | 25 | |
| 282 | | 282 | |
| 283 | indices = gtk_tree_path_get_indices(path); | 283 | indices = gtk_tree_path_get_indices(path); |
| 284 | depth = gtk_tree_path_get_depth(path); | 284 | depth = gtk_tree_path_get_depth(path); |
| 285 | | 285 | //if (depth != 1) printf("%d\n", depth); |
| 286 | /* we do not allow children */ | 286 | /* we do not allow children */ |
| 287 | g_assert(depth == 1); /* depth 1 = top level; a list only has top level nodes and no | 287 | g_assert(depth == 1); /* depth 1 = top level; a list only has top level nodes and no |
| children */ | | children */ |
| 288 | | 288 | |
| 291 | if ( n >= custom_list->filtered_rows_count || n < 0 ) | 291 | if ( n >= custom_list->filtered_rows_count || n < 0 ) |
| 292 | return false; | 292 | return false; |
| 293 | | 293 | |
| 294 | /* We simply store a pointer to our custom record in the iter */ | | |
| 295 | iter->stamp = custom_list->stamp; | 294 | iter->stamp = custom_list->stamp; |
| 296 | iter->user_data = GINT_TO_POINTER(n); | 295 | iter->user_data = GINT_TO_POINTER(n); |
| 297 | #if 0 // unreferenced | 296 | #if 0 // unreferenced |
| 317 | | 316 | |
| 318 | g_return_val_if_fail (CUSTOM_IS_LIST(tree_model), null); | 317 | g_return_val_if_fail (CUSTOM_IS_LIST(tree_model), null); |
| 319 | g_return_val_if_fail (iter != null, null); | 318 | g_return_val_if_fail (iter != null, null); |
| 320 | g_return_val_if_fail (iter->user_data != null, null); | | |
| 321 | | 319 | |
| 322 | path = gtk_tree_path_new(); | 320 | path = gtk_tree_path_new(); |
| 323 | gtk_tree_path_append_index(path, GPOINTER_TO_INT(iter->user_data)); | 321 | gtk_tree_path_append_index(path, GPOINTER_TO_INT(iter->user_data)); |
| 569 | return newcustomlist; | 567 | return newcustomlist; |
| 570 | } | 568 | } |
| 571 | | 569 | |
| | 570 | struct B { |
| | 571 | struct B * next; |
| | 572 | char buf[16352]; |
| | 573 | }; |
| | 574 | |
| | 575 | struct { |
| | 576 | struct B * first; |
| | 577 | int space; |
| | 578 | } D = { 0,0 }; |
| | 579 | |
| | 580 | |
| | 581 | static char * dupstr(const char * str) |
| | 582 | { |
| | 583 | int l = strlen(str) + 1; |
| | 584 | struct B * b; |
| | 585 | |
| | 586 | if (D.space < l) { |
| | 587 | b = (struct B *)malloc(sizeof *b); |
| | 588 | if (b == null) |
| | 589 | die("Out of Memory!\n"); |
| | 590 | b->next = D.first; |
| | 591 | D.first = b; |
| | 592 | D.space = sizeof D.first->buf; |
| | 593 | } |
| | 594 | else |
| | 595 | b = D.first; |
| | 596 | |
| | 597 | D.space -= l; |
| | 598 | char * p = &b->buf[D.space]; |
| | 599 | memcpy(p, str, l); |
| | 600 | |
| | 601 | return p; |
| | 602 | } |
| | 603 | |
| | 604 | static void dupstr_free(void) |
| | 605 | { |
| | 606 | struct B * p = D.first; |
| | 607 | if (p == null) |
| | 608 | return; |
| | 609 | while (1) { |
| | 610 | struct B * q = p->next; |
| | 611 | free(p); |
| | 612 | if (q == null) |
| | 613 | break; |
| | 614 | p = q; |
| | 615 | } |
| | 616 | D.first = null; |
| | 617 | D.space = 0; |
| | 618 | } |
| 572 | | 619 | |
| 573 | /***************************************************************************** | 620 | /***************************************************************************** |
| 574 | * | 621 | * |
| 581 | * | 628 | * |
| 582 | *****************************************************************************/ | 629 | *****************************************************************************/ |
| 583 | | 630 | |
| 584 | static char * dupstr(const char * str) | | |
| 585 | { | | |
| 586 | // improve later -- for single-shot destruction -- now leaks mem! | | |
| 587 | return g_strdup(str); | | |
| 588 | } | | |
| 589 | | 631 | |
| 590 | void | 632 | void |
| 591 | custom_list_append(CustomList * list, | 633 | custom_list_append(CustomList * list, |
| 631 | * sizeof *list->filtered_rows); | 673 | * sizeof *list->filtered_rows); |
| 632 | if (list->filtered_rows == null) | 674 | if (list->filtered_rows == null) |
| 633 | exit(19); | 675 | exit(19); |
| | 676 | // if empty list, might add one dummy line (for information) |
| 634 | custom_list_filter(list, channelindex, compare); | 677 | custom_list_filter(list, channelindex, compare); |
| 635 | } | 678 | } |
| 636 | | 679 | |
| 637 | /* detach first !!! */ | | |
| 638 | void custom_list_clear(CustomList * list) | 680 | void custom_list_clear(CustomList * list) |
| 639 | { | 681 | { |
| 640 | for (unsigned int i = 0; list->all_rows[i]; i++) { | 682 | for (unsigned int i = 0; list->all_rows[i]; i++) { |
| 643 | free(list->filtered_rows); | 685 | free(list->filtered_rows); |
| 644 | list->filtered_rows = null; | 686 | list->filtered_rows = null; |
| 645 | | 687 | |
| 646 | /* clear dupstr()ings */ | 688 | dupstr_free(); |
| 647 | | 689 | |
| 648 | list->all_rows_count = 0; | 690 | list->all_rows_count = 0; |
| 649 | list->filtered_rows_count = 0; | 691 | list->filtered_rows_count = 0; |
| 659 | return list->filtered_rows[indx]; | 701 | return list->filtered_rows[indx]; |
| 660 | } | 702 | } |
| 661 | | 703 | |
| | 704 | CustomRecord * custom_list_get_abs_record(CustomList * list, int indx) |
| | 705 | { |
| | 706 | if (indx >= list->all_rows_count) |
| | 707 | return null; |
| | 708 | int i = indx / 1000; |
| | 709 | int j = indx % 1000; |
| | 710 | |
| | 711 | return &list->all_rows[i][j]; |
| | 712 | } |
| | 713 | |
| | 714 | |
| 662 | int custom_list_get_id(CustomList * list, int indx) | 715 | int custom_list_get_id(CustomList * list, int indx) |
| 663 | { | 716 | { |
| 664 | if (indx >= list->filtered_rows_count) | 717 | if (indx >= list->filtered_rows_count) |
| 666 | return list->filtered_rows[indx]->id; | 719 | return list->filtered_rows[indx]->id; |
| 667 | } | 720 | } |
| 668 | | 721 | |
| 669 | // FIXME: add suggested new position for view | | |
| 670 | void custom_list_filter(CustomList * list, int channelindex, char * compare) | 722 | void custom_list_filter(CustomList * list, int channelindex, char * compare) |
| 671 | { | 723 | { |
| 672 | int fi = 0, clen = strlen(compare); | 724 | int fi = 0, clen = strlen(compare); |
| | 725 | |
| | 726 | if (list->all_rows_count == 0) { |
| | 727 | list->filtered_rows_count = 0; |
| | 728 | return; |
| | 729 | } |
| 673 | | 730 | |
| 674 | for (int i = 0; i < 1000; i++) | 731 | for (int i = 0; i < 1000; i++) |
| 675 | for (int j = 0; j < 1000; j++) { | 732 | for (int j = 0; j < 1000; j++) { |
| 676 | CustomRecord * record = &list->all_rows[i][j]; | 733 | CustomRecord * record = &list->all_rows[i][j]; |
| 677 | if (record->day == null) { i = 1000; break; } | 734 | if (record->day == null) { i = 1000; break; } |
| | 735 | record->filtered_position = fi; |
| 678 | if (channelindex && channelindex != record->channelindex) | 736 | if (channelindex && channelindex != record->channelindex) |
| 679 | continue; | 737 | continue; |
| 680 | if (clen && strstr(record->program, compare) != 0) | 738 | if (clen && strcasestr(record->program, compare) == null) |
| 681 | continue; | 739 | continue; |
| 682 | record->filtered_position = fi; | | |
| 683 | list->filtered_rows[fi++] = record; | 740 | list->filtered_rows[fi++] = record; |
| 684 | } | 741 | } |
| 685 | list->filtered_rows_count = fi; | 742 | list->filtered_rows_count = fi; |
| 686 | #if 0 | 743 | #if 0 |
| 687 | printf("all rows: %d, filtered_rows: %d\n", | 744 | printf("all rows: %d, filtered_rows: %d compare '%s'\n", |
| 688 | list->all_rows_count, list->filtered_rows_count); | 745 | list->all_rows_count, list->filtered_rows_count, compare); |
| 689 | #endif | 746 | #endif |
| 690 | } | 747 | } |
| tvkaista-0.975/tvkaista_gtkui.c | | tvkaista-0.976/tvkaista_gtkui.c |
| 6 | WARN="$WARN -W -Wwrite-strings -Wcast-qual -Wshadow" # -Wconversion | 6 | WARN="$WARN -W -Wwrite-strings -Wcast-qual -Wshadow" # -Wconversion |
| 7 | FLAGS=`pkg-config --cflags --libs gtk+-2.0 | sed 's/-I/-isystem '/g` | 7 | FLAGS=`pkg-config --cflags --libs gtk+-2.0 | sed 's/-I/-isystem '/g` |
| 8 | ver=`sed -n 's/Version=//p' tvkaista.desktop` | 8 | ver=`sed -n 's/Version=//p' tvkaista.desktop` |
| 9 | OPTS="$WARN $FLAGS -DVERSION=$ver" # -DCDATE=\"`date`\"" | 9 | OPTS="$WARN $FLAGS -DVERSION=$ver -fstack-protector" |
| 10 | case $1 in '') set x -ggdb | 10 | case $1 in '') set x -ggdb |
| 11 | #case $1 in '') set x -O2 ### set x -ggdb | 11 | #case $1 in '') set x -O2 ### set x -ggdb |
| 12 | shift ;; esac; | 12 | shift ;; esac; |
| 67 | | 67 | |
| 68 | #if 1 | 68 | #if 1 |
| 69 | #define DBG 1 | 69 | #define DBG 1 |
| | 70 | #define DBG0 0 |
| 70 | #define d1(x) do { printf x; } while (0) | 71 | #define d1(x) do { printf x; } while (0) |
| 71 | #define d0(x) do {} while (0) | 72 | #define d0(x) do {} while (0) |
| 72 | #else | 73 | #else |
| 73 | #define DBG 0 | 74 | #define DBG 0 |
| | 75 | #define DBG0 0 |
| 74 | #define d1(x) do {} while (0) | 76 | #define d1(x) do {} while (0) |
| 75 | #define d0(x) do {} while (0) | 77 | #define d0(x) do {} while (0) |
| 76 | #endif | 78 | #endif |
| 116 | int prgfd[32]; | 118 | int prgfd[32]; |
| 117 | int indx; | 119 | int indx; |
| 118 | int prevabsindx; | 120 | int prevabsindx; |
| | 121 | |
| | 122 | int abspos; |
| | 123 | int refindx; |
| | 124 | char daytime[8]; |
| 119 | } G; | 125 | } G; |
| 120 | | 126 | |
| 121 | /* widgets in separate structure, for code readability */ | 127 | /* widgets in separate structure, for code readability */ |
| 132 | // XXX make better later... | 138 | // XXX make better later... |
| 133 | const char G_helper[] = "./tvkaista-helper.pl"; | 139 | const char G_helper[] = "./tvkaista-helper.pl"; |
| 134 | | 140 | |
| | 141 | /* XXX combine with clean_data */ |
| 135 | void init_G(void) | 142 | void init_G(void) |
| 136 | { | 143 | { |
| 137 | memset(&G, 0, sizeof G); | 144 | memset(&G, 0, sizeof G); |
| 139 | G.indx = G.prevabsindx = -1; | 146 | G.indx = G.prevabsindx = -1; |
| 140 | for (unsigned int i = 0; i < sizeof G.prgfd / sizeof G.prgfd[0]; i++) | 147 | for (unsigned int i = 0; i < sizeof G.prgfd / sizeof G.prgfd[0]; i++) |
| 141 | G.prgfd[i] = -1; | 148 | G.prgfd[i] = -1; |
| | 149 | G.abspos = 0; G.refindx = -1; |
| 142 | } | 150 | } |
| 143 | | 151 | |
| 144 | FILE * runhelper(const char * format, ...) | 152 | FILE * runhelper(const char * format, ...) |
| 160 | return popen(cmdline, "r"); | 168 | return popen(cmdline, "r"); |
| 161 | } | 169 | } |
| 162 | | 170 | |
| | 171 | // XXX error checking ! |
| | 172 | void get_visible_range(int * first, int * last) |
| | 173 | { |
| | 174 | GtkTreePath * fp, * lp; |
| | 175 | GtkTreeIter iter; |
| | 176 | |
| | 177 | if (W.listmodel->filtered_rows_count == 0) { |
| | 178 | *first = *last = 0; |
| | 179 | return; |
| | 180 | } |
| | 181 | gtk_tree_view_get_visible_range(GTK_TREE_VIEW(W.listview), &fp, &lp); |
| | 182 | |
| | 183 | gtk_tree_model_get_iter(GTK_TREE_MODEL(W.listmodel), &iter, fp); |
| | 184 | *first = GPOINTER_TO_INT(iter.user_data); |
| | 185 | gtk_tree_model_get_iter(GTK_TREE_MODEL(W.listmodel), &iter, lp); |
| | 186 | *last = GPOINTER_TO_INT(iter.user_data); |
| | 187 | gtk_tree_path_free(fp); |
| | 188 | gtk_tree_path_free(lp); |
| | 189 | } |
| | 190 | |
| | 191 | bool idle_set_refindx(void) |
| | 192 | { |
| | 193 | int f, l; |
| | 194 | get_visible_range(&f, &l); |
| | 195 | G.refindx = f; |
| | 196 | return false; |
| | 197 | } |
| | 198 | |
| | 199 | void scroll_to_indx(int indx) |
| | 200 | { |
| | 201 | if (indx == 0 && W.listmodel->filtered_rows_count == 0) |
| | 202 | return; |
| | 203 | GtkTreeIter iter; |
| | 204 | memset(&iter, 0, sizeof iter); |
| | 205 | d0(("scroll to index %d\n", indx)); |
| | 206 | iter.user_data = GINT_TO_POINTER(indx); |
| | 207 | GtkTreePath * path = gtk_tree_model_get_path(GTK_TREE_MODEL(W.listmodel), |
| | 208 | &iter); |
| | 209 | gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(W.listview), path, |
| | 210 | null, true, 0, 0); |
| | 211 | gtk_tree_path_free(path); |
| | 212 | g_idle_add(idle_set_refindx, null); |
| | 213 | } |
| | 214 | |
| 163 | void refilter_model(void) | 215 | void refilter_model(void) |
| 164 | { | 216 | { |
| | 217 | int f, l; |
| | 218 | get_visible_range(&f, &l); |
| | 219 | if (f != G.refindx) { |
| | 220 | d0(("old refindx: %d, f %d, old abspos %d\n", G.refindx, f, G.abspos)); |
| | 221 | G.abspos = custom_list_get_record(W.listmodel, f)->absolute_position; |
| | 222 | d0(("new abspos %d\n", G.abspos)); |
| | 223 | } |
| 165 | //g_object_ref(W.listfilter); // there will be 1 reference always... | 224 | //g_object_ref(W.listfilter); // there is 1 reference always... |
| 166 | gtk_tree_view_set_model(GTK_TREE_VIEW(W.listview), null); | 225 | gtk_tree_view_set_model(GTK_TREE_VIEW(W.listview), null); |
| 167 | #if 1 | 226 | #if DBG0 |
| 168 | struct timeval st, et; | 227 | struct timeval st, et; |
| 169 | gettimeofday(&st, null); | 228 | gettimeofday(&st, null); |
| 170 | #endif | 229 | #endif |
| 171 | custom_list_filter(W.listmodel, G.channelfilter, G.compare); | 230 | custom_list_filter(W.listmodel, G.channelfilter, G.compare); |
| 172 | #if 1 | 231 | #if DBG0 |
| 173 | gettimeofday(&et, null); | 232 | gettimeofday(&et, null); |
| 174 | printf("%.3f\n", (float)(et.tv_sec - st.tv_sec) * 1000 | 233 | printf("filter time: %.3f\n", (float)(et.tv_sec - st.tv_sec) * 1000 |
| 175 | + (float)(et.tv_usec - st.tv_usec) / 1000); | 234 | + (float)(et.tv_usec - st.tv_usec) / 1000); |
| 176 | #endif | 235 | #endif |
| 177 | | 236 | |
| 178 | gtk_tree_view_set_model(GTK_TREE_VIEW(W.listview), | 237 | gtk_tree_view_set_model(GTK_TREE_VIEW(W.listview), |
| 179 | GTK_TREE_MODEL(W.listmodel)); | 238 | GTK_TREE_MODEL(W.listmodel)); |
| | 239 | |
| | 240 | scroll_to_indx(custom_list_get_abs_record(W.listmodel, |
| | 241 | G.abspos)->filtered_position); |
| | 242 | |
| 180 | //g_object_unref(W.listfilter); // there will be 1 reference always... | 243 | //g_object_unref(W.listfilter); // there is 1 reference always... |
| 181 | } | 244 | } |
| 182 | | 245 | |
| 183 | // after filter make unselected -- and G.indx == -1 | 246 | // after filter make unselected -- and G.indx == -1 |
| 354 | | 417 | |
| 355 | void day_clicked(int promille) | 418 | void day_clicked(int promille) |
| 356 | { | 419 | { |
| 357 | printf("day_clicked(%d) (no action, yet)\n", promille); | 420 | int f, l, n, p; |
| | 421 | get_visible_range(&f, &l); |
| | 422 | n = l - f; |
| | 423 | if (n == 0) return; |
| | 424 | char * day = W.listmodel->filtered_rows[f]->day; |
| | 425 | if (f != G.refindx) |
| | 426 | xstrlcpy(G.daytime, W.listmodel->filtered_rows[f]->time, |
| | 427 | sizeof G.daytime); |
| | 428 | |
| | 429 | if (promille < 500) { |
| | 430 | for (p = f > 0? f - 1: 0; p > 0; p--) { |
| | 431 | if (strcmp(W.listmodel->filtered_rows[p]->day, day) != 0) |
| | 432 | break; |
| | 433 | } |
| | 434 | day = W.listmodel->filtered_rows[p]->day; |
| | 435 | for (p = p; p >= 0; p--) { |
| | 436 | if (strcmp(W.listmodel->filtered_rows[p]->time, G.daytime) < 0) |
| | 437 | break; |
| | 438 | if (strcmp(W.listmodel->filtered_rows[p]->day, day) != 0) |
| | 439 | break; |
| | 440 | } |
| | 441 | if (p != 0) |
| | 442 | p++; |
| | 443 | } |
| | 444 | else { |
| | 445 | int m = W.listmodel->filtered_rows_count - n; |
| | 446 | for (p = f + 1; p < m; p++) { |
| | 447 | if (strcmp(W.listmodel->filtered_rows[p]->day, day) != 0) |
| | 448 | break; |
| | 449 | } |
| | 450 | day = W.listmodel->filtered_rows[p]->day; |
| | 451 | for (p = p; p < m; p++) { |
| | 452 | if (strcmp(W.listmodel->filtered_rows[p]->time, G.daytime) >= 0) |
| | 453 | break; |
| | 454 | if (strcmp(W.listmodel->filtered_rows[p]->day, day) != 0) |
| | 455 | break; |
| | 456 | } |
| | 457 | } |
| | 458 | d0(("day_clicked(%d) f %d p %d %s\n", promille, f, p, day)); |
| | 459 | |
| | 460 | scroll_to_indx(p); |
| | 461 | G.abspos = custom_list_get_record(W.listmodel, p)->absolute_position; |
| 358 | } | 462 | } |
| 359 | | 463 | |
| 360 | void time_clicked(int promille) | 464 | void time_clicked(int promille) |
| 361 | { | 465 | { |
| 362 | printf("time_clicked(%d) (no action, yet)\n", promille); | 466 | int f, l, n, p; |
| | 467 | get_visible_range(&f, &l); |
| | 468 | n = l - f; |
| | 469 | if (n == 0) return; |
| | 470 | |
| | 471 | if (promille < 500) { |
| | 472 | p = f - n - 1; |
| | 473 | if (p < 0) |
| | 474 | p = 0; |
| | 475 | } |
| | 476 | else { |
| | 477 | p = l + n - 1; |
| | 478 | if (p > W.listmodel->filtered_rows_count) |
| | 479 | p = W.listmodel->filtered_rows_count; |
| | 480 | p -= n; |
| | 481 | } |
| | 482 | d0(("time_clicked(%d) -- %d %d %d %d\n", promille, f, l, n, p)); |
| | 483 | scroll_to_indx(p); |
| | 484 | xstrlcpy(G.daytime, W.listmodel->filtered_rows[p]->time, |
| | 485 | sizeof G.daytime); |
| | 486 | G.abspos = custom_list_get_record(W.listmodel, p)->absolute_position; |
| 363 | } | 487 | } |
| 364 | | 488 | |
| 365 | void channel_clicked(int promille) | 489 | void channel_clicked(int promille) |
| 366 | { | 490 | { |
| 367 | #if 0 | | |
| 368 | printf("channel_clicked(%d) %d %d\n", promille, | 491 | d0(("channel_clicked(%d) %d %d\n", promille, |
| 369 | G.channelfilter, G.maxchannelindex); | 492 | G.channelfilter, G.maxchannelindex)); |
| 370 | #endif | 493 | |
| 371 | if (promille < 300) { | 494 | if (promille < 300) { |
| 372 | if (G.channelfilter <= 1) | 495 | if (G.channelfilter <= 1) |
| 373 | G.channelfilter = G.maxchannelindex; | 496 | G.channelfilter = G.maxchannelindex; |
| 688 | const char * speeds[] = { "300k", "1M", "2M", "8M" }; | 811 | const char * speeds[] = { "300k", "1M", "2M", "8M" }; |
| 689 | const char nspeeds = sizeof speeds / sizeof speeds[0]; | 812 | const char nspeeds = sizeof speeds / sizeof speeds[0]; |
| 690 | | 813 | |
| | 814 | /* XXX combine with init_G */ |
| 691 | void clean_data(void) | 815 | void clean_data(void) |
| 692 | { | 816 | { |
| 693 | custom_list_clear(W.listmodel); | 817 | custom_list_clear(W.listmodel); |
| 694 | for (unsigned int i = 0; i < sizeof G.prgfd / sizeof G.prgfd[0]; i++) | 818 | for (unsigned int i = 0; i < sizeof G.prgfd / sizeof G.prgfd[0]; i++) |
| 695 | if (G.prgfd[i] >= 0) { close(G.prgfd[i]); G.prgfd[i] = -1; } | 819 | if (G.prgfd[i] >= 0) { close(G.prgfd[i]); G.prgfd[i] = -1; } |
| 696 | G.indx = G.prevabsindx = -1; | 820 | G.indx = G.prevabsindx = -1; |
| | 821 | G.abspos = 0; G.refindx = -1; |
| 697 | G.compare[0] = '\0'; | 822 | G.compare[0] = '\0'; |
| 698 | G.channelfilter = 0; | 823 | G.channelfilter = 0; |
| 699 | G.maxchannelindex = 0; | 824 | G.maxchannelindex = 0; |
| 858 | "Ctrl-C tässä lopettaa tvkaista-ohjelman ja mahdollisesti suoritettavan\n" | 983 | "Ctrl-C tässä lopettaa tvkaista-ohjelman ja mahdollisesti suoritettavan\n" |
| 859 | "tallennuksen/tv-ohjelman seurannan. Myöhemmin toimii ehkä paremmin.\n" | 984 | "tallennuksen/tv-ohjelman seurannan. Myöhemmin toimii ehkä paremmin.\n" |
| 860 | "\n" | 985 | "\n" |
| 861 | "Sitä ennen ehkä kuitenkin selausominaisuudet...\n" | 986 | "Selaus toimii <päiva>, <klo> ja <kanava> -\"painikkeilla\". Ne katsovat\n" |
| | 987 | "napsautuskohdasta vaakatasossa halutaanko selata eteen- vai taaksepäin\n" |
| | 988 | "<kanava> -\"painike\" palauttaa kaikki kanavat näkyviin keskialueen\n" |
| | 989 | "napsautuksella\n" |
| 862 | "\n" | 990 | "\n" |
| 863 | "Tallenteiden sijaintipaikka on $HOME/.tvkaista/tallenteet/.\n" | 991 | "Tallenteiden sijaintipaikka on $HOME/.tvkaista/tallenteet/.\n" |
| 864 | "\n"; | 992 | "\n"; |