// Compilation command: // - release: gcc task_tracker.c -Wall -O2 -m64 -lncurses -o task_tracker.x64 // - debug : gcc task_tracker.c -Wall -g3 -m64 -lncurses -o task_tracker.x64 #include #include #include #include #include #include #include #include #define STR_(X) #X // Convert to string. #define STR(X) STR_(X) // Force argument expansions before converting to string. #define MAX_TASK_NAME 127 #define FIRST_DAY_OF_WEEK 1 // (0-6, Sunday = 0) #define LOG_FILE_NAME "log.txt" #define DB_FILE_NAME "database.bin" #define DB_CSV_PATH_NAME "./database.csv" struct task_event { char* name; time_t start; time_t end; }; typedef struct { uint32_t hash; // uint32_t time[sizeof(DAYS_OF_WEEK)]; // #define DAYS_ON_WEEK sizeof(DAYS_OF_WEEK) // uint32_t time[DAYS_ON_WEEK]; uint32_t time[7]; char name[MAX_TASK_NAME+1]; // Allow space for null termination char. } task_t; const char* DB_FILE_SIGNATURE = "TTBF:1.0"; const uint8_t FILE_SIGNATURE_SIZE = sizeof(DB_FILE_SIGNATURE); const size_t TASK_INFO_SIZE = sizeof(task_t); const char* DAYS_OF_WEEK[] = { "sun", "mon", "tue", "wed", "thu", "fri", "sat" }; const uint8_t DAYS_ON_WEEK = sizeof(DAYS_OF_WEEK)/sizeof(char*); task_t* tasks = NULL; uint32_t tasks_count = 0; uint32_t tasks_capacity = 0; int selected_task = -1; char** tasks_names = NULL; uint32_t tasks_names_size = 0; uint32_t tasks_names_capacity = 0; char* replace_char(char* string, char find, char replace){ char *idx = string; while((idx = strchr(idx, find)) != NULL) { *idx = replace; *idx++; } return string; } void print_task(const task_t* task) { printf("name: '%s'\n", task->name); printf("hash: '%" PRIu32 "'\n", task->hash); printf("t[0]: '%" PRIu32 "'\n", task->time[0]); printf("t[1]: '%" PRIu32 "'\n", task->time[1]); printf("t[2]: '%" PRIu32 "'\n", task->time[2]); printf("t[3]: '%" PRIu32 "'\n", task->time[3]); printf("t[4]: '%" PRIu32 "'\n", task->time[4]); printf("t[5]: '%" PRIu32 "'\n", task->time[5]); printf("t[6]: '%" PRIu32 "'\n", task->time[6]); } void store_database(const task_t* database, uint32_t number_of_entries) { // TODO Maybe move this to global level? const char* DB_FILE_SIGNATURE = "TTBF:1.0"; const uint8_t FILE_SIGNATURE_SIZE = sizeof(DB_FILE_SIGNATURE); const size_t TASK_INFO_SIZE = sizeof(task_t); // Open file. FILE* file = fopen("./" DB_FILE_NAME, "w"); if (file == NULL) { fprintf(stderr, "Failed to open database file: %s.\n", strerror(errno)); // TODO Fix message. return; } fwrite(DB_FILE_SIGNATURE, sizeof(char), FILE_SIGNATURE_SIZE, file); fwrite(&number_of_entries, sizeof(number_of_entries), 1, file); fwrite(database, TASK_INFO_SIZE, number_of_entries, file); fclose(file); } uint32_t load_database(task_t** database) { // TODO Maybe move this to global level? const char* DB_FILE_SIGNATURE = "TTBF:1.0"; const uint8_t FILE_SIGNATURE_SIZE = sizeof(DB_FILE_SIGNATURE); const size_t TASK_INFO_SIZE = sizeof(task_t); // Open file. FILE* file = fopen("./" DB_FILE_NAME, "r"); if (file == NULL) { fprintf(stderr, "Failed to open database file: %s.\n", strerror(errno)); // TODO Fix message. return 0; } // Validate file signature. char file_signature[FILE_SIGNATURE_SIZE]; fread(&file_signature, sizeof(char), FILE_SIGNATURE_SIZE, file); if (strncmp(file_signature, DB_FILE_SIGNATURE, FILE_SIGNATURE_SIZE) != 0) { fprintf(stderr, "Invalid file signature.\n"); return 0; } // Read number of entries. uint32_t number_of_entries; fread(&number_of_entries, sizeof(number_of_entries), 1, file); // Read database entries. *database = calloc(number_of_entries, TASK_INFO_SIZE); fread(*database, TASK_INFO_SIZE, number_of_entries, file); // Make sure we are reading all the file. assert(fgetc(file) == EOF); fclose(file); return number_of_entries; } void export_database(const task_t* database, uint32_t number_of_entries, const char* path_name) { assert(database != NULL); assert(path_name != NULL); FILE* file = fopen(path_name, "w"); fprintf(file, "%s,%s,%s,%s,%s,%s,%s,%s\n", "task", DAYS_OF_WEEK[0], DAYS_OF_WEEK[1], DAYS_OF_WEEK[2], DAYS_OF_WEEK[3], DAYS_OF_WEEK[4], DAYS_OF_WEEK[5], DAYS_OF_WEEK[6] ); for (uint32_t idx = 0; idx < number_of_entries; idx++) { const task_t* task = &database[idx]; fprintf(file, "%s,%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 ",%" PRIu32 "\n", task->name, task->time[0], task->time[1], task->time[2], task->time[3], task->time[4], task->time[5], task->time[6] ); } fclose(file); } uint32_t import_database(task_t** database, const char* path_name) { assert(database != NULL); assert(path_name != NULL); FILE* file = fopen(path_name, "r"); if (file == NULL) { fprintf(stderr, "Failed to open database file: %s.\n", strerror(errno)); // TODO Fix message. return 0; } uint32_t number_of_entries = 0; task_t task; int error; fscanf(file, "%*[^\n]\n"); do { // TODO prepare memory for database error = fscanf(file, "%" STR(MAX_TASK_NAME) "[^,],%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 "\n", task.name, &task.time[0], &task.time[1], &task.time[2], &task.time[3], &task.time[4], &task.time[5], &task.time[6] ); // TODO At this point we are reading one more... that's why we are reduccing the number_of_entries after the while. task.hash = hash_string(task.name); print_task(&task); number_of_entries++; } while(error > 0); assert(number_of_entries == 3); // if (error != EOF) { // fprintf(stderr, "Failed to parse database file: %s.\n", strerror(errno)); // } fclose(file); return number_of_entries; } uint32_t CRC32(const uint8_t data[], size_t data_length) { static const uint32_t crc32_table[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; uint32_t crc32 = 0xFFFFFFFFu; for (size_t i = 0; i < data_length; i++) { const uint32_t lookupIndex = (crc32 ^ data[i]) & 0xff; crc32 = (crc32 >> 8) ^ crc32_table[lookupIndex]; } // Finalize the CRC-32 value by inverting all the bits crc32 ^= 0xFFFFFFFFu; return crc32; } uint32_t hash_string(const char* string) { size_t data_length = strlen(string); uint8_t* data = (uint8_t*)string; return CRC32(data, data_length); } void add_task(char* name) { // Exit if task has already been added. uint32_t name_hash = CRC32((uint8_t*)name, sizeof(name)); for (uint32_t idx = 0; idx < tasks_count; idx++) { if (name_hash == tasks[idx].hash && strcmp(name, tasks[idx].name) == 0) { return; } } // Expand tasks capacity if required. if (tasks_count >= tasks_capacity) { tasks_capacity = tasks_capacity == 0 ? 16 : tasks_capacity << 1; tasks = realloc(tasks, sizeof(task_t) * tasks_capacity); } // Add new task entry. task_t* new_task = &tasks[tasks_count]; memset(new_task, '0', sizeof(task_t)); strncpy(new_task->name, name, MAX_TASK_NAME); new_task->name[MAX_TASK_NAME] = '\0'; printf(">>> %s\n", new_task->name); // TODO debug new_task->hash = name_hash; tasks_count++; } void add_task_event(char* name, uint64_t start, uint64_t end) { // TODO Missing the task_event array. } void prototype() { /////////////////////////////////////////////////////////////////////////// // Get current day of the week. fprintf(stderr, "# current day of the week --------------------- |\n"); time_t now_ut = time(NULL); uint8_t week_day = localtime(&now_ut)->tm_wday; fprintf(stderr, "> %d\n", week_day); /////////////////////////////////////////////////////////////////////////// // Store database from memory to binary file. /* fprintf(stderr, "# store database ------------------------------ |\n"); task_t task; memset(&task, '0', TASK_INFO_SIZE); strncpy(task.name, "TASK-00 : Sample task name.", MAX_TASK_NAME+1); task.time[0] = 0; task.time[1] = 10; task.time[2] = 11; task.time[3] = 12; task.time[4] = 333; task.time[5] = 555; task.time[6] = 777; task.hash = hash_string(task.name); print_task(&task); store_database(&task, 1); */ /////////////////////////////////////////////////////////////////////////// // Load database from binary file to memory. fprintf(stderr, "# load database ------------------------------- |\n"); task_t* task_load = NULL; uint32_t number_of_entries_load = load_database(&task_load); fprintf(stderr, "> loaded %" PRIu32 " entries.\n", number_of_entries_load); print_task(task_load); free(task_load); /////////////////////////////////////////////////////////////////////////// // Export database to CSV file. /* fprintf(stderr, "# export to CSV ------------------------------- |\n"); export_database(&task, 1); export_database(NULL, 1, ""); */ fprintf(stderr, "# import from CSV ----------------------------- |\n"); task_t* task_import = NULL; uint32_t number_of_entries_import = import_database(&task_import, DB_CSV_PATH_NAME); fprintf(stderr, "> imported %" PRIu32 " entries.\n", number_of_entries_import); print_task(task_import); free(task_import); return; const char* csv_head = "task_name,start,end"; const char* csv_line[] = { "PI-0000,1659479138,1659482738", "PI-0001,1659479127,1659482727", "XPTO-01 : testing long name,1659379138,1659382738", "XPTO-01 : testing long nameXPTO-01 : testing long nameXPTO-01 : testing long nameXPTO-01 : testing long nameXPTO-01 : testing long nameXPTO-01 : testing long nameXPTO-01 : testing long nameXPTO-01 : testing long name,123,124", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccc:ddddddddddddddddddddddddddddddddddddd:eeeeeeeeeeeeeeeeeeeeee:fffffffffffffffffff,123,456", "Olá vamos cantar uma canção.,1659279127,1659282727", "[ TST-00 á],1659579138,1659582738", "[ XPTO- 01,1659179127,1659182727", "[ TST-00 á],1659479138,1659482738", "[ XPTO- 01,1659429127,1659482727", "[ TST-00 á],1658479138,1658482738", "[ XPTO- 01,1659669127,1659672727", "[ TST-00 á],1658879138,1658882738", "[ XPTO- 01,1656579127,1656582727", "[ TST-00 á],1659439138,1659492738", "[ XPTO- 01,1655579127,1655682727", "[ TST-00 á],1657679138,1657782738", "[ XPTO- 01,1658179127,1658382727", "[ TST-00 á],1651479138,1651482738", "[ XPTO- 01,1659479127,1659482727", "[ TST-00 á],1659079138,1659082738", "[ XPTO- 01,1659379127,1659382727", }; // const char* csv_line = "1659479138,1659482738"; // const char* csv_line = "zZ[ ã ]Yy,123"; // char name[] = { 'a', 'b', 'c', '\0' }; char* name; uint64_t start; uint64_t end; printf("--- --- àè.ªãº.éá --- ---\n"); ////////////////////////////////////////////////// // TODO Use this to parse the tasks names. TODO // // TODO WIP TODO WIP TODO WIP TODO const char* task_info_A = "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vel turpis nunc eget lorem. Non pulvinar neque laoreet suspendisse interdum consectetur libero id,165147,14790,9138,1,2,3,4"; const char* task_info_B = "Lorem,165147,14790,9138,1,2,3,4"; #define COISA #define SPACER "%*[^,]" const char* format = "%" STR(MAX_TASK_NAME) "[^,]" SPACER ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32; // task_t task_A; // sscanf(task_info_A, format, // task_A.name, // &task_A.time[0], // &task_A.time[1], // &task_A.time[2], // &task_A.time[3], // &task_A.time[4], // &task_A.time[5], // &task_A.time[6] // ); // TODO WIP const char* format_X = "%" STR(MAX_TASK_NAME) "[^,]"; task_t task_A; sscanf(task_info_A, format_X, task_A.name ); // TODO WIP const char* format_Y = "%*[^,],%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32 ",%" SCNu32; sscanf(task_info_A, format_Y, &task_A.time[0], &task_A.time[1], &task_A.time[2], &task_A.time[3], &task_A.time[4], &task_A.time[5], &task_A.time[6] ); // TODO WIP // task_t task_B; // sscanf(task_info_B,format, // task_B.name, // &task_B.time[0], // &task_B.time[1], // &task_B.time[2], // &task_B.time[3], // &task_B.time[4], // &task_B.time[5], // &task_B.time[6] // ); // TODO WIP task_t task_B; sscanf(task_info_B,format_X, task_B.name ); // TODO WIP sscanf(task_info_B,format_Y, &task_B.time[0], &task_B.time[1], &task_B.time[2], &task_B.time[3], &task_B.time[4], &task_B.time[5], &task_B.time[6] ); // TODO WIP printf("--------------------------------------------------\n"); printf("name: '%s'\n", task_A.name); printf("t[0]: '%d'\n", task_A.time[0]); printf("t[1]: '%d'\n", task_A.time[1]); printf("t[2]: '%d'\n", task_A.time[2]); printf("t[3]: '%d'\n", task_A.time[3]); printf("t[4]: '%d'\n", task_A.time[4]); printf("t[5]: '%d'\n", task_A.time[5]); printf("t[6]: '%d'\n", task_A.time[6]); printf("name: '%s'\n", task_B.name); printf("t[0]: '%d'\n", task_B.time[0]); printf("t[1]: '%d'\n", task_B.time[1]); printf("t[2]: '%d'\n", task_B.time[2]); printf("t[3]: '%d'\n", task_B.time[3]); printf("t[4]: '%d'\n", task_B.time[4]); printf("t[5]: '%d'\n", task_B.time[5]); printf("t[6]: '%d'\n", task_B.time[6]); printf("--------------------------------------------------\n"); /////////////////////////////////////////////////////////////// uint32_t lines_count = sizeof(csv_line)/sizeof(char*); for (uint32_t idx = 0; idx < lines_count; idx++) { // TODO The following sscanf is allocating memory for the name... we should remove it. // uint32_t max_task_name // TODO The m modifier requires us to free the memory returned. sscanf(csv_line[idx], "%" STR(MAX_TASK_NAME) "m[^,\n],%" SCNu64 ",%" SCNu64, &name, &start, &end); // TODO WIP add_task(name); // printf("bazinga: %s : %d : %d\n", name, start, end); // printf("bazinga: %s : %.19s : %.19s\n", name, ctime(&start), ctime(&end)); printf("bazonga: %s\n", tasks[tasks_count-1].name); } printf("### ### --------- ### ###\n"); // tasks_names = // Free tasks names. for (uint32_t idx = tasks_names_size; idx > 0; idx--) { printf("> %s\n", tasks_names[idx-1]); // @dam TODO debug free(tasks_names[idx-1]); } free(tasks_names); return; // tasks_names = malloc( ... time_t x = time(NULL); // x = (time_t)((1U << 32) - 1); printf("%s\n", ctime(&x)); x = x<<1; printf("%s\n", ctime(&x)); x += 1; printf("%s\n", ctime(&x)); x = x<<1; printf("%s\n", ctime(&x)); x = x<<1; printf("%s\n", ctime(&x)); x = x<<1; printf("%s\n", ctime(&x)); x = x<<1; printf("%s\n", ctime(&x)); } void draw_table() { task_t asd; } void draw_header() { const char *table_headers[] = { "Task", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Total" }; const int table_headers_size = sizeof(table_headers)/sizeof(char*); int row,col; /* to store the number of rows and the number of colums of the screen */ initscr(); /* start the curses mode */ getmaxyx(stdscr,row,col); /* get the number of rows and columns */ mvaddch(0, 0, ACS_ULCORNER); for (int idx = 0; idx < table_headers_size; idx++) { if (idx > 0) { addch(ACS_TTEE); // printw(" %c", ACS_PLUS); } addch(ACS_HLINE); printw(" %s ", table_headers[idx]); addch(ACS_HLINE); } int cursor_y, cursor_x; getyx(stdscr, cursor_y, cursor_x); for (int idx = cursor_x; idx < col-1; idx++) { addch(ACS_HLINE); } addch(ACS_URCORNER); } void draw_footer() { const char *app_name = "Task Tracker"; const char *app_version = "v1.0"; int row, col; /* to store the number of rows and the number of colums of the screen */ initscr(); /* start the curses mode */ getmaxyx(stdscr,row,col); /* get the number of rows and columns */ printw("Row %d", row); mvaddch(row-1, 0, ACS_LLCORNER); addch(' '); printw(app_name); addch(' '); for (int idx = strlen(app_name) + 3; idx < col - strlen(app_version) - 3; idx ++) { addch(ACS_HLINE); } addch(' '); printw(app_version); addch(' '); addch(ACS_LRCORNER); } WINDOW *create_newwin(int height, int width, int starty, int startx); void destroy_win(WINDOW *local_win); int main(int argc, char *argv[]) { prototype(); return 0; WINDOW *my_win; int startx, starty, width, height; int ch; initscr(); /* Start curses mode */ cbreak(); /* Line buffering disabled, Pass on * everty thing to me */ keypad(stdscr, TRUE); /* I need that nifty F1 */ curs_set(0); // Set cursor invisible. height = 3; width = 10; starty = (LINES - height) / 2; /* Calculating for a center placement */ startx = (COLS - width) / 2; /* of the window */ printw("Press F1 to exit"); refresh(); my_win = create_newwin(height, width, starty, startx); int rows; int colums; ch = KEY_RESIZE; do { switch(ch) { case KEY_RESIZE: erase(); break; case KEY_LEFT: destroy_win(my_win); my_win = create_newwin(height, width, starty,--startx); break; case KEY_RIGHT: destroy_win(my_win); my_win = create_newwin(height, width, starty,++startx); break; case KEY_UP: destroy_win(my_win); my_win = create_newwin(height, width, --starty,startx); break; case KEY_DOWN: destroy_win(my_win); my_win = create_newwin(height, width, ++starty,startx); break; } draw_header(); draw_table(); draw_footer(); } while((ch = getch()) != KEY_F(1)); endwin(); return 0; } WINDOW *create_newwin(int height, int width, int starty, int startx) { WINDOW *local_win; local_win = newwin(height, width, starty, startx); box(local_win, 0 , 0); /* 0, 0 gives default characters * for the vertical and horizontal * lines */ wrefresh(local_win); /* Show that box */ return local_win; } void destroy_win(WINDOW *local_win) { /* box(local_win, ' ', ' '); : This won't produce the desired * result of erasing the window. It will leave it's four corners * and so an ugly remnant of window. */ wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' '); /* The parameters taken are * 1. win: the window on which to operate * 2. ls: character to be used for the left side of the window * 3. rs: character to be used for the right side of the window * 4. ts: character to be used for the top side of the window * 5. bs: character to be used for the bottom side of the window * 6. tl: character to be used for the top left corner of the window * 7. tr: character to be used for the top right corner of the window * 8. bl: character to be used for the bottom left corner of the window * 9. br: character to be used for the bottom right corner of the window */ wrefresh(local_win); delwin(local_win); }