static rt_bool_t mainmenu_event_handler(struct rtgui_object *object, rtgui_event_t *event) { switch (event->type) { case RTGUI_EVENT_PAINT: on_draw(RTGUI_WIDGET(object)); break; case RTGUI_EVENT_KBD: { struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd *)event; if ((ekbd->key == RTGUIK_RIGHT) && RTGUI_KBD_IS_UP(ekbd)) { next_page(RTGUI_WIDGET(object)); } else if ((ekbd->key == RTGUIK_LEFT) && RTGUI_KBD_IS_UP(ekbd)) { priv_page(RTGUI_WIDGET(object)); } else { return rtgui_win_event_handler(object, event); } } break; case RTGUI_EVENT_MOUSE_BUTTON: { struct rtgui_event_mouse *emouse; emouse = (struct rtgui_event_mouse *)event; return app_list_view_onmouse(app_list, emouse); } case RTGUI_EVENT_GESTURE: { struct rtgui_event_gesture *gestrure_event = (struct rtgui_event_gesture *)event; switch (gestrure_event->type) { case RTGUI_GESTURE_RIGHT: priv_page(RTGUI_WIDGET(object)); break; case RTGUI_GESTURE_LEFT: next_page(RTGUI_WIDGET(object)); break; } } break; case RTGUI_EVENT_WIN_ACTIVATE: statusbar_set_title(RT_NULL); statusbar_show_back_button(RT_FALSE); return rtgui_win_event_handler(object, event); default: return rtgui_win_event_handler(object, event); } return RT_FALSE; }
bool Oggeyman::fast_forward_to_frame(int frameno) { if (stream_done) return false; int framect = 0; while (framect < frameno && !stream_done) { bool packet_found = false; do { // list through packets to get rid of bad packets // (the function below checks whether the packet is ok) packet_found = next_theora_packet(&ogg_theora_stream_state, &ogg_theora_packet, &theo_state); if (!packet_found) { //try new page bool is_theora_page = false; while (!stream_done && !is_theora_page) { stream_done = !next_page(); if (stream_done) continue; // submit the completed page to the streaming layer with ogg_stream_pagein. // check out the return value - it will be < 0 it the page does not correspond // to the stream whose state we are providing as the first argument is_theora_page = (ogg_stream_pagein( &ogg_theora_stream_state, ¤t_ogg_page) >= 0); } } else { framect++; } } while (!packet_found && !stream_done); } if (framect == frameno && !stream_done) { total_play_time = last_packet_time = get_packet_time(); return true; } return false; }
struct phys_page *search_obj_chain(mm_context *ctx, struct mm_mapping *mapping, uintptr_t fault_addr) { struct mm_object *front_pobj = mapping->object; struct mm_object *pobj = front_pobj; struct phys_page *page; struct phys_page *new_page; uintptr_t fault_page = (uintptr_t)fault_addr & ~0xfff; int prot = PM_USER | (mapping->prot & PM_WRITABLE ? PM_WRITABLE : 0); while (pobj) { rwlock_wrlock(&pobj->lock); page = first_page(pobj); while (page) { if (mapping->start_addr + page->offset == fault_page) { switch (pobj->share_type) { case share_private: // kdebug("Object is private %p\n", fault_page); kpage_map_user((void *)fault_page, page, mm_pgtable_alloc_callback, ctx, ctx->cr3, prot); //mm_ctx_reload(ctx); break; case share_shared: // kdebug("Object is shared %p\n", fault_page); kpage_map_user((void *)fault_page, page, mm_pgtable_alloc_callback, ctx, ctx->cr3, prot); // mm_ctx_reload(ctx); break; case share_cow: // kdebug("%d: Object is cow %p %p\n", get_core_id(), fault_addr, ctx); /* Make a copy of the page and put it in front_pobj */ new_page = kphys_alloc(physmem_state_user); new_page->offset = fault_page - mapping->start_addr; front_pobj->page_list.add_head(new_page); ++front_pobj->npages; memcpy((void *)(pagestruct_to_phys(new_page) + VADDR_PHYSMEM), (void *)(pagestruct_to_phys(page) + VADDR_PHYSMEM), __PAGESIZE); kpage_map_user((void *)fault_page, new_page, mm_pgtable_alloc_callback, ctx, ctx->cr3, PM_WRITABLE | PM_USER); break; default: ; } rwlock_unlock(&pobj->lock); return page; } /* Go to the next one */ page = next_page(pobj, page); } rwlock_unlock(&pobj->lock); pobj = pobj->chain; } return NULL; }
/* * Function that returns the number of pages in the string. */ int count_pages(char *str) { int pages; for (pages = 1; (str = next_page(str)); pages++) ; return pages; }
void PageControl::handle_signal(Input::Signal* signal) { if (signal->get_data() == "prev_page") { prev_page(); } else if (signal->get_data() == "next_page") { next_page(); } else { switch_page(signal->get_data()); } }
/* * This function assigns all the pointers for showstr_vector for the * page_string function, after showstr_vector has been allocated and * showstr_count set. */ void paginate_string(char *str, Descriptor *d) { int i; if (d->showstr_count) *(d->showstr_vector) = str; for (i = 1; i < d->showstr_count && str; i++) str = d->showstr_vector[i] = next_page(str); d->showstr_page = 0; }
bool Oggeyman::init(const char * path) { switch (video_format) { //pixel_format.set(r_offset,g_offset,b_offset,bpp not a_offset); case VF_RGB: pixel_format.set(0, 1, 2, 3); break; case VF_BGR: pixel_format.set(2, 1, 0, 3); break; case VF_RGBA: pixel_format.set(0, 1, 2, 4); break; case VF_BGRA: pixel_format.set(2, 1, 0, 4); break; } this->path = path; // open the input file infptr = fopen(path, "rb"); if (!infptr) { printf("\t failure opening %s\n", path); return false; } // initialize ogg and theora -- none of these have a useful diagnostics implemented ogg_sync_init(&overall_sync_state); theora_info_init(&theo_info); theora_comment_init(&theo_comment); // find theora stream if (!parse_headers()) return false; // bcs we are only interested in theora, // flip through pages until we are sure we are on theora page bool have_page = false; bool is_theora_page = false; do { // we start by checking the page that was read in during header perusal int retval = ogg_stream_pagein(&ogg_theora_stream_state, ¤t_ogg_page); is_theora_page = (retval >= 0); if (!is_theora_page) have_page = next_page(); } while (have_page && !is_theora_page); // initialize theora decoder if (!initialize_theora()) return false; // the user should allocate space for the output buffer, BGRAbuffer return true; }
bool Oggeyman::parse_headers() { bool found_theora = false; // The whole page belongs to one particular stream, but to find out what is the type of // the payload, we have to go all the way down to the packet level and try to decode it. // In this first loop we will only go through the header pages, and find which // stream belongs to theora - we will save that info in theora_stream_state structure // later, we will use that info to look only at the pages belonging to our stream of interest // (here I am counting on having (or following) only one stream- theora)s ogg_stream_state probe; int pagect = 0; while (next_page()) { pagect++; // is this a header page at all? if (!is_header_page(¤t_ogg_page)) break; bool wrote_stream_state = false; if (ogg_stream_init(&probe, ogg_page_serialno(¤t_ogg_page))) return false; // submit the completed page to the streaming layer with ogg_stream_pagein ogg_stream_pagein(&probe, ¤t_ogg_page); // if I understand this correctly, theora wants theora_decode_header to be called // "until it returns 0": theora_decode_header is wrapper for th_decode_headerin // [th_decode_headerin] Decodes one header packet. // This should be called repeatedly with the packets at the beginning of the // stream until it returns 0. // That is why we call is_theora_stream, even though we have initialized the theora stream_state. // (I.e. one would think that we need to find only one theora header, but no.) if (is_theora_stream(&probe, &ogg_theora_packet)) { found_theora = true; if (! ogg_theora_stream_state.serialno) { memcpy(&ogg_theora_stream_state, &probe, sizeof(probe)); wrote_stream_state = true; } } if (!wrote_stream_state) ogg_stream_clear(&probe); } return found_theora; }
static void mm_change_commit(mm_context *ctx, struct mm_mapping *mapping, int flags) { struct mm_object *pobj = mapping->object->chain; struct phys_page *page; while (pobj && pobj->share_type == share_private) { rwlock_wrlock(&pobj->lock); page = first_page(pobj); while (page) { kpage_map_prot(ctx->cr3, (void *)(mapping->start_addr + page->offset), flags); /* Go to the next one */ page = next_page(pobj, page); } pobj->share_type = share_cow; rwlock_unlock(&pobj->lock); pobj = pobj->chain; } // uint64_t p; // uintptr_t start, end; // // start = mapping->start_addr; // end = start + mapping->length - 1; // // start &= ~0xfff; // end = __PAGEROUND(end); // //kdebug("s=%016lx e=%016lx\n", start, end); // // for (p=start; p<end; p+=__PAGESIZE) // { // //kdebug("Unmapping %016lx\n", p); // kpage_map_prot(ctx->cr3, (void *)p, flags); // } }
void * initarm(struct arm_boot_params *abp) { #define next_chunk2(a,b) (((a) + (b)) &~ ((b)-1)) #define next_page(a) next_chunk2(a,PAGE_SIZE) struct pv_addr kernel_l1pt; struct pv_addr dpcpu; int loop, i; u_int l1pagetable; vm_offset_t freemempos; vm_offset_t freemem_pt; vm_offset_t afterkern; vm_offset_t freemem_after; vm_offset_t lastaddr; uint32_t memsize; /* kernel text starts where we were loaded at boot */ #define KERNEL_TEXT_OFF (abp->abp_physaddr - PHYSADDR) #define KERNEL_TEXT_BASE (KERNBASE + KERNEL_TEXT_OFF) #define KERNEL_TEXT_PHYS (PHYSADDR + KERNEL_TEXT_OFF) lastaddr = parse_boot_param(abp); arm_physmem_kernaddr = abp->abp_physaddr; set_cpufuncs(); /* NB: sets cputype */ pcpu_init(pcpup, 0, sizeof(struct pcpu)); PCPU_SET(curthread, &thread0); if (envmode == 1) kern_envp = static_env; /* Do basic tuning, hz etc */ init_param1(); /* * We allocate memory downwards from where we were loaded * by RedBoot; first the L1 page table, then NUM_KERNEL_PTS * entries in the L2 page table. Past that we re-align the * allocation boundary so later data structures (stacks, etc) * can be mapped with different attributes (write-back vs * write-through). Note this leaves a gap for expansion * (or might be repurposed). */ freemempos = abp->abp_physaddr; /* macros to simplify initial memory allocation */ #define alloc_pages(var, np) do { \ freemempos -= (np * PAGE_SIZE); \ (var) = freemempos; \ /* NB: this works because locore maps PA=VA */ \ memset((char *)(var), 0, ((np) * PAGE_SIZE)); \ } while (0) #define valloc_pages(var, np) do { \ alloc_pages((var).pv_pa, (np)); \ (var).pv_va = (var).pv_pa + (KERNVIRTADDR - abp->abp_physaddr); \ } while (0) /* force L1 page table alignment */ while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0) freemempos -= PAGE_SIZE; /* allocate contiguous L1 page table */ valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); /* now allocate L2 page tables; they are linked to L1 below */ for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) { valloc_pages(kernel_pt_table[loop], L2_TABLE_SIZE / PAGE_SIZE); } else { kernel_pt_table[loop].pv_pa = freemempos + (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) * L2_TABLE_SIZE_REAL; kernel_pt_table[loop].pv_va = kernel_pt_table[loop].pv_pa + (KERNVIRTADDR - abp->abp_physaddr); } } freemem_pt = freemempos; /* base of allocated pt's */ /* * Re-align allocation boundary so we can map the area * write-back instead of write-through for the stacks and * related structures allocated below. */ freemempos = PHYSADDR + 0x100000; /* * Allocate a page for the system page mapped to V0x00000000 * This page will just contain the system vectors and can be * shared by all processes. */ valloc_pages(systempage, 1); /* Allocate dynamic per-cpu area. */ valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE); dpcpu_init((void *)dpcpu.pv_va, 0); /* Allocate stacks for all modes */ valloc_pages(irqstack, IRQ_STACK_SIZE); valloc_pages(abtstack, ABT_STACK_SIZE); valloc_pages(undstack, UND_STACK_SIZE); valloc_pages(kernelstack, KSTACK_PAGES); alloc_pages(minidataclean.pv_pa, 1); valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE); /* * Now construct the L1 page table. First map the L2 * page tables into the L1 so we can replace L1 mappings * later on if necessary */ l1pagetable = kernel_l1pt.pv_va; /* Map the L2 pages tables in the L1 page table */ pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1), &kernel_pt_table[KERNEL_PT_SYS]); pmap_link_l2pt(l1pagetable, IXP425_IO_VBASE, &kernel_pt_table[KERNEL_PT_IO]); pmap_link_l2pt(l1pagetable, IXP425_MCU_VBASE, &kernel_pt_table[KERNEL_PT_IO + 1]); pmap_link_l2pt(l1pagetable, IXP425_PCI_MEM_VBASE, &kernel_pt_table[KERNEL_PT_IO + 2]); pmap_link_l2pt(l1pagetable, KERNBASE, &kernel_pt_table[KERNEL_PT_BEFOREKERN]); pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR, 0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, PHYSADDR + 0x100000, 0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, KERNEL_TEXT_PHYS, next_chunk2(((uint32_t)lastaddr) - KERNEL_TEXT_BASE, L1_S_SIZE), VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); freemem_after = next_page((int)lastaddr); afterkern = round_page(next_chunk2((vm_offset_t)lastaddr, L1_S_SIZE)); for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) { pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000, &kernel_pt_table[KERNEL_PT_AFKERNEL + i]); } pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); /* Map the Mini-Data cache clean area. */ xscale_setup_minidata(l1pagetable, afterkern, minidataclean.pv_pa); /* Map the vector page. */ pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); if (cpu_is_ixp43x()) arm_devmap_bootstrap(l1pagetable, ixp435_devmap); else arm_devmap_bootstrap(l1pagetable, ixp425_devmap); /* * Give the XScale global cache clean code an appropriately * sized chunk of unmapped VA space starting at 0xff000000 * (our device mappings end before this address). */ xscale_cache_clean_addr = 0xff000000U; cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); setttb(kernel_l1pt.pv_pa); cpu_tlb_flushID(); cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)); /* * Pages were allocated during the secondary bootstrap for the * stacks for different CPU modes. * We must now set the r13 registers in the different CPU modes to * point to these stacks. * Since the ARM stacks use STMFD etc. we must set r13 to the top end * of the stack memory. */ set_stackptrs(0); /* * We must now clean the cache again.... * Cleaning may be done by reading new data to displace any * dirty data in the cache. This will have happened in setttb() * but since we are boot strapping the addresses used for the read * may have just been remapped and thus the cache could be out * of sync. A re-clean after the switch will cure this. * After booting there are no gross relocations of the kernel thus * this problem will not occur after initarm(). */ cpu_idcache_wbinv_all(); cpu_setup(); /* ready to setup the console (XXX move earlier if possible) */ cninit(); /* * Fetch the RAM size from the MCU registers. The * expansion bus was mapped above so we can now read 'em. */ if (cpu_is_ixp43x()) memsize = ixp435_ddram_size(); else memsize = ixp425_sdram_size(); undefined_init(); init_proc0(kernelstack.pv_va); arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL); pmap_curmaxkvaddr = afterkern + PAGE_SIZE; vm_max_kernel_address = 0xe0000000; pmap_bootstrap(pmap_curmaxkvaddr, &kernel_l1pt); msgbufp = (void*)msgbufpv.pv_va; msgbufinit(msgbufp, msgbufsize); mutex_init(); /* * Add the physical ram we have available. * * Exclude the kernel, and all the things we allocated which immediately * follow the kernel, from the VM allocation pool but not from crash * dumps. virtual_avail is a global variable which tracks the kva we've * "allocated" while setting up pmaps. * * Prepare the list of physical memory available to the vm subsystem. */ arm_physmem_hardware_region(PHYSADDR, memsize); arm_physmem_exclude_region(freemem_pt, KERNPHYSADDR - freemem_pt, EXFLAG_NOALLOC); arm_physmem_exclude_region(freemempos, KERNPHYSADDR - 0x100000 - freemempos, EXFLAG_NOALLOC); arm_physmem_exclude_region(abp->abp_physaddr, virtual_avail - KERNVIRTADDR, EXFLAG_NOALLOC); arm_physmem_init_kernel_globals(); init_param2(physmem); kdb_init(); /* use static kernel environment if so configured */ if (envmode == 1) kern_envp = static_env; return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP - sizeof(struct pcb))); #undef next_page #undef next_chunk2 }
int read_seq_write_rand(command_list *cl, DCB_registered_src *r_src, unsigned char is_overlay, cfile *out_cfh, unsigned long buf_size) { unsigned char *buf; unsigned char *p; unsigned long x, start=0, end=0, len=0; unsigned long max_pos = 0, pos = 0; unsigned long offset; signed long tmp_len; dcb_src_read_func read_func; cfile_window *cfw; u_dcb_src u_src; #define END_POS(x) ((x).src_pos + (x).len) pos = 0; max_pos = 0; if(is_overlay) { read_func = r_src->mask_read_func; } else { read_func = r_src->read_func; } assert(read_func != NULL); u_src = r_src->src_ptr; if(0 != cseek(u_src.cfh, 0, CSEEK_FSTART)) { ap_printf("cseeked failed: bailing, io_error 0\n"); return IO_ERROR; } if((buf = (unsigned char *)malloc(buf_size)) == NULL) { return MEM_ERROR; } // we should *never* go backwards u_src.cfh->state_flags |= CFILE_FLAG_BACKWARD_SEEKS; while(start < cl->com_count) { if(pos < cl->full_command[start].src_pos) { pos = cl->full_command[start].src_pos; max_pos = END_POS(cl->full_command[start]); } else { while(start < cl->com_count && pos > cl->full_command[start].src_pos) { start++; } if(start == cl->com_count) continue; pos = cl->full_command[start].src_pos; max_pos = MAX(max_pos, END_POS(cl->full_command[start])); } if(end < start) { end = start; } while(end < cl->com_count && cl->full_command[end].src_pos < max_pos) { max_pos = MAX(max_pos, END_POS(cl->full_command[end])); end++; } if(pos == max_pos) { continue; } while(pos < max_pos) { len = MIN(max_pos - pos, buf_size); x = read_func(u_src, pos, buf, len); // if(len < max_pos - pos) // v0printf("buffered %lu, max was %lu\n", len, max_pos - pos); if(len != x){ ap_printf("x=%lu, pos=%lu, len=%lu\n", x, pos, len); ap_printf("bailing, io_error 2\n"); free(buf); return IO_ERROR; } for(x=start; x < end; x++) { offset = MAX(cl->full_command[x].src_pos, pos); tmp_len = MIN(END_POS(cl->full_command[x]), pos + len) - offset; if(tmp_len > 0) { if(cl->full_command[x].ver_pos + (offset - cl->full_command[x].src_pos) != cseek(out_cfh, cl->full_command[x].ver_pos + (offset - cl->full_command[x].src_pos), CSEEK_FSTART)) { ap_printf("bailing, io_error 3\n"); free(buf); return IO_ERROR; } if(is_overlay) { p = buf + offset - pos; cfw = expose_page(out_cfh); if(cfw->write_end == 0) { cfw->write_start = cfw->pos; } while(buf + offset - pos + tmp_len > p) { if(cfw->pos == cfw->end) { cfw->write_end = cfw->end; cfw = next_page(out_cfh); if(cfw->end == 0) { ap_printf("bailing from applying overlay mask in read_seq_writ_rand\n"); free(buf); return IO_ERROR; } } cfw->buff[cfw->pos] += *p; p++; cfw->pos++; } cfw->write_end = cfw->pos; } else { if(tmp_len != cwrite(out_cfh, buf + offset - pos, tmp_len)) { ap_printf("bailing, io_error 4\n"); free(buf); return IO_ERROR; } } } } pos += len; } } u_src.cfh->state_flags &= ~CFILE_FLAG_BACKWARD_SEEKS; free(buf); return 0; }
char *request(const char *prompt, const char * const default_string, const bool alpha_allowed, const int completion_type, const bool prefer_utf8) { set_attr(0); input_buffer[pos = len = offset = 0] = 0; encoding = ENC_ASCII; x = start_x = print_prompt(prompt); init_history(); if (default_string) { strncpy(input_buffer, default_string, MAX_INPUT_LINE_LEN); len = strlen(input_buffer); encoding = detect_encoding(input_buffer, len); input_refresh(); } bool first_char_typed = true, last_char_completion = false, selection = false; while(true) { assert(input_buffer[len] == 0); move_cursor(ne_lines - 1, x); int c; input_class ic; do c = get_key_code(); while((ic = CHAR_CLASS(c)) == IGNORE); /* ISO 10646 characters *above 256* can be added only to UTF-8 lines, or ASCII lines (making them, of course, UTF-8). */ if (ic == ALPHA && c > 0xFF && encoding != ENC_ASCII && encoding != ENC_UTF8) ic = INVALID; if (ic != TAB) last_char_completion = false; if (ic == TAB && !completion_type) ic = ALPHA; switch(ic) { case INVALID: alert(); break; case ALPHA: if (first_char_typed) { input_buffer[len = 0] = 0; clear_to_eol(); } if (encoding == ENC_ASCII && c > 0x7F) encoding = prefer_utf8 || c > 0xFF ? ENC_UTF8 : ENC_8_BIT; int c_len = encoding == ENC_UTF8 ? utf8seqlen(c) : 1; int c_width = output_width(c); assert(c_len > 0); if (len <= MAX_INPUT_LINE_LEN - c_len && (alpha_allowed || (c < 0x100 && isxdigit(c)) || c=='X' || c=='x')) { memmove(&input_buffer[pos + c_len], &input_buffer[pos], len - pos + 1); if (c_len == 1) input_buffer[pos] = c; else utf8str(c, &input_buffer[pos]); len += c_len; move_cursor(ne_lines - 1, x); if (x < ne_columns - c_width) { if (pos == len - c_len) output_char(c, 0, encoding); else if (char_ins_del_ok) insert_char(c, 0, encoding); else input_refresh(); } input_move_right(true); } break; case RETURN: selection = true; break; case TAB: if (completion_type == COMPLETE_FILE || completion_type == COMPLETE_SYNTAX) { bool quoted = false; char *prefix, *completion, *p; if (len && input_buffer[len - 1] == '"') { input_buffer[len - 1] = 0; if (prefix = strrchr(input_buffer, '"')) { quoted = true; prefix++; } else input_buffer[len - 1] = '"'; } if (!quoted) { prefix = strrchr(input_buffer, ' '); if (prefix) prefix++; else prefix = input_buffer; } if (last_char_completion || completion_type == COMPLETE_SYNTAX) { if (completion_type == COMPLETE_FILE ) completion = p = request_files(prefix, true); else completion = p = request_syntax(prefix, true); reset_window(); if (completion) { if (*completion) selection = true; else completion++; } } else { if (completion_type == COMPLETE_FILE ) completion = p = complete_filename(prefix); else completion = p = request_syntax(prefix, true); last_char_completion = true; if (!completion) alert(); } if (completion && (prefix - input_buffer) + strlen(completion) + 1 < MAX_INPUT_LINE_LEN) { const encoding_type completion_encoding = detect_encoding(completion, strlen(completion)); if (encoding == ENC_ASCII || completion_encoding == ENC_ASCII || encoding == completion_encoding) { strcpy(prefix, completion); if (quoted) strcat(prefix, "\""); len = strlen(input_buffer); pos = offset = 0; x = start_x; if (encoding == ENC_ASCII) encoding = completion_encoding; input_move_to_eol(); if (quoted) input_move_left(false); input_refresh(); } else alert(); } else if (quoted) strcat(prefix, "\""); free(p); } break; case COMMAND: if (c < 0) c = -c - 1; const int a = parse_command_line(key_binding[c], NULL, NULL, false); if (a >= 0) { switch(a) { case LINEUP_A: case LINEDOWN_A: case MOVESOF_A: case MOVEEOF_A: case PAGEUP_A: case PAGEDOWN_A: case NEXTPAGE_A: case PREVPAGE_A: if (history_buff) { switch(a) { case LINEUP_A: line_up(history_buff); break; case LINEDOWN_A: line_down(history_buff); break; case MOVESOF_A: move_to_sof(history_buff); break; case MOVEEOF_A: move_to_bof(history_buff); break; case PAGEUP_A: case PREVPAGE_A: prev_page(history_buff); break; case PAGEDOWN_A: case NEXTPAGE_A: next_page(history_buff); break; } /* In some cases, the default displayed on the command line will be the same as the first history item. In that case we skip it. */ if (first_char_typed == true && a == LINEUP_A && history_buff->cur_line_desc->line && !strncmp(history_buff->cur_line_desc->line, input_buffer, history_buff->cur_line_desc->line_len)) line_up(history_buff); if (history_buff->cur_line_desc->line) { strncpy(input_buffer, history_buff->cur_line_desc->line, min(history_buff->cur_line_desc->line_len,MAX_INPUT_LINE_LEN)); input_buffer[min(history_buff->cur_line_desc->line_len,MAX_INPUT_LINE_LEN)] = 0; len = strlen(input_buffer); encoding = detect_encoding(input_buffer, len); } else { input_buffer[len = 0] = 0; encoding = ENC_ASCII; } x = start_x; pos = 0; offset = 0; input_refresh(); } break; case MOVELEFT_A: input_move_left(true); break; case MOVERIGHT_A: input_move_right(true); break; case BACKSPACE_A: if (pos == 0) break; input_move_left(true); case DELETECHAR_A: if (len > 0 && pos < len) { int c_len = encoding == ENC_UTF8 ? utf8len(input_buffer[pos]) : 1; int c_width = get_char_width(&input_buffer[pos], encoding); memmove(&input_buffer[pos], &input_buffer[pos + c_len], len - pos - c_len + 1); len -= c_len; if (input_buffer_is_ascii()) encoding = ENC_ASCII; if (char_ins_del_ok) { int i, j; move_cursor(ne_lines - 1, x); delete_chars(c_width); for(i = x, j = pos; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns - c_width; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j < len) { move_cursor(ne_lines - 1, i); while(j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns) { output_char(get_char(&input_buffer[j], encoding), 0, encoding); i += get_char_width(&input_buffer[j], encoding); j = next_pos(input_buffer, j, encoding); } } } else input_refresh(); } break; case DELETELINE_A: move_cursor(ne_lines - 1, start_x); clear_to_eol(); input_buffer[len = pos = offset = 0] = 0; encoding = ENC_ASCII; x = start_x; break; case DELETEEOL_A: input_buffer[len = pos] = 0; clear_to_eol(); if (input_buffer_is_ascii()) encoding = ENC_ASCII; break; case MOVEINCUP_A: if (x != start_x) { pos = offset; x = start_x; break; } case MOVESOL_A: input_move_to_sol(); break; case MOVEINCDOWN_A: { int i, j; for(i = x, j = pos; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j != pos && j < len) { pos = j; x = i; break; } } case MOVEEOL_A: input_move_to_eol(); break; case TOGGLESEOL_A: case TOGGLESEOF_A: if (pos != 0) input_move_to_sol(); else input_move_to_eol(); break; case PREVWORD_A: input_prev_word(); break; case NEXTWORD_A: input_next_word(); break; case REFRESH_A: input_refresh(); break; case PASTE_A: input_paste(); break; case AUTOCOMPLETE_A: input_autocomplete(); break; case ESCAPE_A: return NULL; default: break; } } break; default: break; } if (selection) { const line_desc * const last = (line_desc *)history_buff->line_desc_list.tail_pred->prev; assert(input_buffer[len] == 0); if (history_buff->num_lines == 0 || len != last->line_len || strncmp(input_buffer, last->line, last->line_len)) add_to_history(input_buffer); return input_buffer; } first_char_typed = false; } }
void mm_context_dump(mm_context *ctx) { return ; struct mm_mapping *pmap; // Process *proc; kdebug("---------------------------------------------\n"); // if ((proc = proctable.procobj_getref(ctx->pid)) == NULL) // { // kdebug("MM_CONTEXT - ERROR\n"); // return; // } // kdebug("MM_CONTEXT: pid=%d %s\n", ctx->pid, proc->name); kdebug("ctx %p\n", ctx); kdebug("cr3 %p\n", ctx->cr3); kdebug("low_addr %p\n", ctx->low_addr); kdebug("hi_addr %p\n", ctx->hi_addr); kdebug("anon_addr %p\n", ctx->anon_addr); pmap = first_mapping(ctx); while (pmap) { struct mm_object *pobj; kdebug("%p, %p %p ", pmap, pmap->start_addr, pmap->start_addr+pmap->length-1); if (pmap->prot & PROT_READ) kdebug("r"); else kdebug("-"); if (pmap->prot & PROT_WRITE) kdebug("w"); else kdebug("-"); if (pmap->prot & PROT_EXEC) kdebug("x"); else kdebug("-"); kdebug("\n"); pobj = pmap->object; while (pobj) { switch (pobj->share_type) { case share_cow: kdebug("cow - "); break; case share_private: kdebug("pri - "); break; case share_shared: kdebug("shr - "); break; default: kdebug("unk - "); break; } kdebug(" %d pages\n", pobj->npages); int page_count = 0; struct phys_page *page; page = first_page(pobj); while (page) { if (pobj->npages < 20) { kdebug(" %p\n", pmap->start_addr + page->offset); } ++page_count; page = next_page(pobj, page); } pobj = pobj->chain; } pmap = next_mapping(ctx, pmap); } kdebug("---------------------------------------------\n"); }
UI_Mainwindow::UI_Mainwindow() { int i, j, k; setMinimumSize(640, 480); setWindowTitle(PROGRAM_NAME); setWindowIcon(QIcon(":/images/edf.png")); myfont = new QFont; monofont = new QFont; #ifdef Q_OS_WIN32 myfont->setFamily("Tahoma"); myfont->setPixelSize(11); monofont->setFamily("courier"); monofont->setPixelSize(12); #else myfont->setFamily("Arial"); myfont->setPixelSize(12); monofont->setFamily("andale mono"); monofont->setPixelSize(12); #endif QApplication::setFont(*myfont); setlocale(LC_NUMERIC, "C"); pixelsizefactor = 0.0294382; x_pixelsizefactor = 0.0294382; viewtime_indicator_type = 1; mainwindow_title_type = 1; check_for_updates = 1; use_threads = 1; auto_dpi = 1; show_annot_markers = 1; show_baselines = 1; clip_to_pane = 0; annotations_onset_relative = 1; auto_reload_mtg = 1; read_biosemi_status_signal = 1; read_nk_trigger_signal = 1; maxfilesize_to_readin_annotations = 10485760000LL; exit_in_progress = 0; live_stream_active = 0; playback_realtime_active = 0; signal_averaging_active = 0; live_stream_update_interval = 500; powerlinefreq = 50; mousewheelsens = 10; amplitude_doubler = 10; timescale_doubler = 10; default_amplitude = 100; linear_interpol = 0; recent_montagedir[0] = 0; recent_savedir[0] = 0; recent_opendir[0] = 0; recent_colordir[0] = 0; cfg_app_version[0] = 0; for(i=0; i<MAXSPECTRUMDIALOGS; i++) { spectrumdialog[i] = NULL; } for(i=0; i<MAXAVERAGECURVEDIALOGS; i++) { averagecurvedialog[i] = NULL; } for(i=0; i<MAXZSCOREDIALOGS; i++) { zscoredialog[i] = NULL; } spectrum_colorbar = (struct spectrum_markersblock *)calloc(1, sizeof(struct spectrum_markersblock)); for(i=0; i < MAXSPECTRUMMARKERS; i++) { spectrum_colorbar->freq[i] = 1.0; spectrum_colorbar->color[i] = Qt::white; } spectrum_colorbar->items = 5; spectrum_colorbar->freq[0] = 4.0; spectrum_colorbar->freq[1] = 8.0; spectrum_colorbar->freq[2] = 12.0; spectrum_colorbar->freq[3] = 30.0; spectrum_colorbar->freq[4] = 100.0; spectrum_colorbar->color[0] = Qt::darkRed; spectrum_colorbar->color[1] = Qt::darkGreen; spectrum_colorbar->color[2] = Qt::darkBlue; spectrum_colorbar->color[3] = Qt::darkCyan; spectrum_colorbar->color[4] = Qt::darkMagenta; spectrum_colorbar->method = 0; spectrum_colorbar->auto_adjust = 1; spectrum_colorbar->max_colorbar_value = 10.0; maxdftblocksize = 1000; import_annotations_var = (import_annotations_var_block *)calloc(1, sizeof(struct import_annotations_var_block)); strcpy(import_annotations_var->separator, "tab"); import_annotations_var->format = 1; import_annotations_var->onsettimeformat = 0; import_annotations_var->onsetcolumn = 1; import_annotations_var->descriptioncolumn = 2; import_annotations_var->useduration = 0; import_annotations_var->durationcolumn = 3; import_annotations_var->datastartline = 1; import_annotations_var->dceventbittime = 10; import_annotations_var->triggerlevel = 500.0; import_annotations_var->manualdescription = 0; import_annotations_var->description[0] = 0; import_annotations_var->ignoreconsecutive = 0; export_annotations_var = (export_annotations_var_block *)calloc(1, sizeof(struct export_annotations_var_block)); export_annotations_var->separator = 0; export_annotations_var->format = 1; export_annotations_var->duration = 0; average_period = 0.3; average_ratio = 0; average_upsidedown = 0; average_bw = 0; spectrum_bw = 0; spectrum_sqrt = 0; spectrum_vlog = 0; spectrumdock_sqrt = 0; spectrumdock_vlog = 0; z_score_var.crossoverfreq = 7.5; z_score_var.z_threshold = 0.0; z_score_var.zscore_page_len = 30; z_score_var.zscore_error_detection = 80; z_score_var.z_hysteresis = 0.0; raw2edf_var.sf = 256; raw2edf_var.chns = 1; raw2edf_var.phys_max = 3000; raw2edf_var.straightbinary = 0; raw2edf_var.endianness = 0; raw2edf_var.samplesize = 2; raw2edf_var.offset = 0; raw2edf_var.skipblocksize = 0; raw2edf_var.skipbytes = 1; strcpy(raw2edf_var.phys_dim, "uV"); read_general_settings(); maincurve = new ViewCurve(this); dpix = maincurve->logicalDpiX(); dpiy = maincurve->logicalDpiY(); if(auto_dpi) { pixelsizefactor = 1.0 / ((double)dpiy / 2.54); x_pixelsizefactor = 1.0 / ((double)dpix / 2.54); } read_color_settings(); video_player = (struct video_player_struct *)calloc(1, sizeof(struct video_player_struct)); video_player->poll_timer = 100; live_stream_timer = new QTimer; live_stream_timer->setSingleShot(true); QObject::connect(live_stream_timer, SIGNAL(timeout()), this, SLOT(live_stream_timer_func())); video_poll_timer = new QTimer; video_poll_timer->setSingleShot(true); QObject::connect(video_poll_timer, SIGNAL(timeout()), this, SLOT(video_poll_timer_func())); playback_realtime_time = new QTime(); playback_realtime_timer = new QTimer; playback_realtime_timer->setInterval(20); QObject::connect(playback_realtime_timer, SIGNAL(timeout()), this, SLOT(playback_realtime_timer_func())); #if QT_VERSION >= 0x050000 live_stream_timer->setTimerType(Qt::PreciseTimer); video_poll_timer->setTimerType(Qt::PreciseTimer); playback_realtime_timer->setTimerType(Qt::PreciseTimer); #endif setCentralWidget(maincurve); menubar = menuBar(); recent_filesmenu = new QMenu(this); recent_filesmenu->setTitle("Recent files"); connect(recent_filesmenu, SIGNAL(triggered(QAction *)), this, SLOT(recent_file_action_func(QAction *))); close_filemenu = new QMenu(this); close_filemenu->setTitle("Close"); connect(close_filemenu, SIGNAL(triggered(QAction *)), this, SLOT(close_file_action_func(QAction *))); print_img_menu = new QMenu(this); print_img_menu->setTitle("to Image"); print_img_menu->addAction("640 x 480", this, SLOT(print_to_img_640x480())); print_img_menu->addAction("800 x 600", this, SLOT(print_to_img_800x600())); print_img_menu->addAction("1024 x 768", this, SLOT(print_to_img_1024x768())); print_img_menu->addAction("1280 x 1024", this, SLOT(print_to_img_1280x1024())); print_img_menu->addAction("1600 x 1200", this, SLOT(print_to_img_1600x1200())); printmenu = new QMenu(this); printmenu->setTitle("Print"); printmenu->addAction("to Printer", maincurve, SLOT(print_to_printer()), QKeySequence::Print); #if QT_VERSION < 0x050000 printmenu->addAction("to PostScript", maincurve, SLOT(print_to_postscript())); #endif printmenu->addAction("to PDF", maincurve, SLOT(print_to_pdf())); printmenu->addMenu(print_img_menu); printmenu->addAction("to EDF", this, SLOT(print_to_edf())); printmenu->addAction("to BDF", this, SLOT(print_to_bdf())); save_act = new QAction("Save as", this); save_act->setShortcut(QKeySequence::Save); save_act->setEnabled(false); connect(save_act, SIGNAL(triggered()), this, SLOT(save_file())); video_act = new QAction("Start video", this); connect(video_act, SIGNAL(triggered()), this, SLOT(start_stop_video())); video_act->setShortcut(QKeySequence("Ctrl+Shift+V")); filemenu = new QMenu(this); filemenu->setTitle("&File"); filemenu->addAction("Open", this, SLOT(open_new_file()), QKeySequence::Open); filemenu->addSeparator(); filemenu->addAction("Open stream", this, SLOT(open_stream()), QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_O)); filemenu->addSeparator(); #ifdef Q_OS_LINUX filemenu->addAction(video_act); filemenu->addSeparator(); #endif filemenu->addAction("Playback file", this, SLOT(playback_realtime()), QKeySequence("Ctrl+Space")); filemenu->addSeparator(); filemenu->addAction(save_act); filemenu->addMenu(recent_filesmenu); filemenu->addMenu(printmenu); filemenu->addAction("Info", this, SLOT(show_file_info())); filemenu->addMenu(close_filemenu); filemenu->addAction("Close all", this, SLOT(close_all_files()), QKeySequence::Close); filemenu->addAction("Exit", this, SLOT(exit_program()), QKeySequence::Quit); menubar->addMenu(filemenu); signalmenu = new QMenu(this); signalmenu->setTitle("&Signals"); signalmenu->addAction("Properties", this, SLOT(signalproperties_dialog())); signalmenu->addAction("Add", this, SLOT(add_signals_dialog())); signalmenu->addAction("Organize", this, SLOT(organize_signals())); signalmenu->addAction("Remove all", this, SLOT(remove_all_signals())); menubar->addMenu(signalmenu); displaymenu = new QMenu(this); displaymenu->setTitle("&Timescale"); displaymenu->addAction("3 cm/sec", this, SLOT(page_3cmsec())); displaymenu->addSeparator(); page_10u = new QAction("10 uSec/page", this); displaymenu->addAction(page_10u); page_20u = new QAction("20 uSec/page", this); displaymenu->addAction(page_20u); page_50u = new QAction("50 uSec/page", this); displaymenu->addAction(page_50u); page_100u = new QAction("100 uSec/page", this); displaymenu->addAction(page_100u); page_200u = new QAction("200 uSec/page", this); displaymenu->addAction(page_200u); page_500u = new QAction("500 uSec/page", this); displaymenu->addAction(page_500u); page_1m = new QAction("1 mSec/page", this); displaymenu->addAction(page_1m); page_2m = new QAction("2 mSec/page", this); displaymenu->addAction(page_2m); page_5m = new QAction("5 mSec/page", this); displaymenu->addAction(page_5m); page_10m = new QAction("10 mSec/page", this); displaymenu->addAction(page_10m); page_20m = new QAction("20 mSec/page", this); displaymenu->addAction(page_20m); page_50m = new QAction("50 mSec/page", this); displaymenu->addAction(page_50m); page_100m = new QAction("100 mSec/page", this); displaymenu->addAction(page_100m); page_200m = new QAction("200 mSec/page", this); displaymenu->addAction(page_200m); page_500m = new QAction("500 mSec/page", this); displaymenu->addAction(page_500m); page_1 = new QAction("1 Sec/page", this); displaymenu->addAction(page_1); page_2 = new QAction("2 Sec/page", this); displaymenu->addAction(page_2); page_5 = new QAction("5 Sec/page", this); displaymenu->addAction(page_5); page_10 = new QAction("10 Sec/page", this); displaymenu->addAction(page_10); page_15 = new QAction("15 Sec/page", this); displaymenu->addAction(page_15); page_20 = new QAction("20 Sec/page", this); displaymenu->addAction(page_20); page_30 = new QAction("30 Sec/page", this); page_30->setChecked(true); displaymenu->addAction(page_30); page_60 = new QAction("60 Sec/page", this); displaymenu->addAction(page_60); page_300 = new QAction("5 min/page", this); displaymenu->addAction(page_300); page_1200 = new QAction("20 min/page", this); displaymenu->addAction(page_1200); page_3600 = new QAction("1 hour/page", this); displaymenu->addAction(page_3600); displaymenu->addSeparator(); page_div2 = new QAction("Timescale / 2", this); page_div2->setShortcut(QKeySequence::ZoomIn); connect(page_div2, SIGNAL(triggered()), this, SLOT(set_page_div2())); displaymenu->addAction(page_div2); page_mult2 = new QAction("Timescale x 2", this); page_mult2->setShortcut(QKeySequence::ZoomOut); connect(page_mult2, SIGNAL(triggered()), this, SLOT(set_page_mult2())); displaymenu->addAction(page_mult2); displaymenu->addSeparator(); page_user_defined = new QAction("user defined", this); connect(page_user_defined, SIGNAL(triggered()), this, SLOT(set_user_defined_display_time())); displaymenu->addAction(page_user_defined); displaymenu->addSeparator(); page_whole_rec = new QAction("whole recording", this); connect(page_whole_rec, SIGNAL(triggered()), this, SLOT(set_display_time_whole_rec())); displaymenu->addAction(page_whole_rec); menubar->addMenu(displaymenu); DisplayGroup = new QActionGroup(this); DisplayGroup->addAction(page_10u); DisplayGroup->addAction(page_20u); DisplayGroup->addAction(page_50u); DisplayGroup->addAction(page_100u); DisplayGroup->addAction(page_200u); DisplayGroup->addAction(page_500u); DisplayGroup->addAction(page_1m); DisplayGroup->addAction(page_2m); DisplayGroup->addAction(page_5m); DisplayGroup->addAction(page_10m); DisplayGroup->addAction(page_20m); DisplayGroup->addAction(page_50m); DisplayGroup->addAction(page_100m); DisplayGroup->addAction(page_200m); DisplayGroup->addAction(page_500m); DisplayGroup->addAction(page_1); DisplayGroup->addAction(page_2); DisplayGroup->addAction(page_5); DisplayGroup->addAction(page_10); DisplayGroup->addAction(page_15); DisplayGroup->addAction(page_20); DisplayGroup->addAction(page_30); DisplayGroup->addAction(page_60); DisplayGroup->addAction(page_300); DisplayGroup->addAction(page_1200); DisplayGroup->addAction(page_3600); connect(DisplayGroup, SIGNAL(triggered(QAction *)), this, SLOT(set_display_time(QAction *))); amplitudemenu = new QMenu(this); amplitudemenu->setTitle("&Amplitude"); fit_to_pane = new QAction("Fit to pane", this); connect(fit_to_pane, SIGNAL(triggered()), this, SLOT(fit_signals_to_pane())); amplitudemenu->addAction(fit_to_pane); fit_to_dc = new QAction("Adjust offset", this); connect(fit_to_dc, SIGNAL(triggered()), this, SLOT(fit_signals_dc_offset())); amplitudemenu->addAction(fit_to_dc); amplitudemenu->addAction("Offset -> 0", this, SLOT(set_dc_offset_to_zero())); amplitudemenu->addSeparator(); amp_50000 = new QAction("50000", this); amplitudemenu->addAction(amp_50000); amp_20000 = new QAction("20000", this); amplitudemenu->addAction(amp_20000); amp_10000 = new QAction("10000", this); amplitudemenu->addAction(amp_10000); amp_5000 = new QAction("5000", this); amplitudemenu->addAction(amp_5000); amp_2000 = new QAction("2000", this); amplitudemenu->addAction(amp_2000); amp_1000 = new QAction("1000", this); amplitudemenu->addAction(amp_1000); amp_500 = new QAction("500", this); amplitudemenu->addAction(amp_500); amp_200 = new QAction("200", this); amplitudemenu->addAction(amp_200); amp_100 = new QAction("100 (50uV/5mm)", this); amplitudemenu->addAction(amp_100); amp_50 = new QAction("50", this); amplitudemenu->addAction(amp_50); amp_20 = new QAction("20", this); amplitudemenu->addAction(amp_20); amp_10 = new QAction("10", this); amplitudemenu->addAction(amp_10); amp_5 = new QAction("5", this); amplitudemenu->addAction(amp_5); amp_2 = new QAction("2", this); amplitudemenu->addAction(amp_2); amp_1 = new QAction("1", this); amplitudemenu->addAction(amp_1); amp_05 = new QAction("0.5", this); amplitudemenu->addAction(amp_05); amp_02 = new QAction("0.2", this); amplitudemenu->addAction(amp_02); amp_01 = new QAction("0.1", this); amplitudemenu->addAction(amp_01); amp_005 = new QAction("0.05", this); amplitudemenu->addAction(amp_005); amp_002 = new QAction("0.02", this); amplitudemenu->addAction(amp_002); amp_001 = new QAction("0.01", this); amplitudemenu->addAction(amp_001); amp_0005 = new QAction("0.005", this); amplitudemenu->addAction(amp_0005); amp_0002 = new QAction("0.002", this); amplitudemenu->addAction(amp_0002); amp_0001 = new QAction("0.001", this); amplitudemenu->addAction(amp_0001); amp_00005 = new QAction("0.0005", this); amplitudemenu->addAction(amp_00005); amp_00002 = new QAction("0.0002", this); amplitudemenu->addAction(amp_00002); amp_00001 = new QAction("0.0001", this); amplitudemenu->addAction(amp_00001); amplitudemenu->addSeparator(); amp_plus = new QAction("Amplitude x 2", this); amp_plus->setShortcut(Qt::Key_Minus); connect(amp_plus, SIGNAL(triggered()), this, SLOT(set_amplitude_mult2())); amplitudemenu->addAction(amp_plus); amp_minus = new QAction("Amplitude / 2", this); amp_minus->setShortcut(Qt::Key_Plus); connect(amp_minus, SIGNAL(triggered()), this, SLOT(set_amplitude_div2())); amplitudemenu->addAction(amp_minus); menubar->addMenu(amplitudemenu); AmplitudeGroup = new QActionGroup(this); AmplitudeGroup->addAction(amp_00001); AmplitudeGroup->addAction(amp_00002); AmplitudeGroup->addAction(amp_00005); AmplitudeGroup->addAction(amp_0001); AmplitudeGroup->addAction(amp_0002); AmplitudeGroup->addAction(amp_0005); AmplitudeGroup->addAction(amp_001); AmplitudeGroup->addAction(amp_002); AmplitudeGroup->addAction(amp_005); AmplitudeGroup->addAction(amp_01); AmplitudeGroup->addAction(amp_02); AmplitudeGroup->addAction(amp_05); AmplitudeGroup->addAction(amp_1); AmplitudeGroup->addAction(amp_2); AmplitudeGroup->addAction(amp_5); AmplitudeGroup->addAction(amp_10); AmplitudeGroup->addAction(amp_20); AmplitudeGroup->addAction(amp_50); AmplitudeGroup->addAction(amp_100); AmplitudeGroup->addAction(amp_200); AmplitudeGroup->addAction(amp_500); AmplitudeGroup->addAction(amp_1000); AmplitudeGroup->addAction(amp_2000); AmplitudeGroup->addAction(amp_5000); AmplitudeGroup->addAction(amp_10000); AmplitudeGroup->addAction(amp_20000); AmplitudeGroup->addAction(amp_50000); connect(AmplitudeGroup, SIGNAL(triggered(QAction *)), this, SLOT(set_amplitude(QAction *))); filtermenu = new QMenu(this); filtermenu->setTitle("&Filter"); filtermenu->addAction("New", this, SLOT(add_new_filter())); filtermenu->addAction("Adjust", this, SLOT(filterproperties_dialog())); filtermenu->addAction("Remove all", this, SLOT(remove_all_filters())); filtermenu->addSeparator(); filtermenu->addAction("Spike", this, SLOT(add_spike_filter())); filtermenu->addAction("Remove all spike filters", this, SLOT(remove_all_spike_filters())); menubar->addMenu(filtermenu); // math_func_menu = new QMenu(this); // math_func_menu->setTitle("&Math"); // math_func_menu->addAction("New", this, SLOT(add_new_math_func())); // math_func_menu->addAction("Remove all", this, SLOT(remove_all_math_funcs())); // menubar->addMenu(math_func_menu); load_predefined_mtg_act[0] = new QAction("Empty", this); load_predefined_mtg_act[0]->setShortcut(Qt::Key_F1); load_predefined_mtg_act[1] = new QAction("Empty", this); load_predefined_mtg_act[1]->setShortcut(Qt::Key_F2); load_predefined_mtg_act[2] = new QAction("Empty", this); load_predefined_mtg_act[2]->setShortcut(Qt::Key_F3); load_predefined_mtg_act[3] = new QAction("Empty", this); load_predefined_mtg_act[3]->setShortcut(Qt::Key_F4); load_predefined_mtg_act[4] = new QAction("Empty", this); load_predefined_mtg_act[4]->setShortcut(Qt::Key_F5); load_predefined_mtg_act[5] = new QAction("Empty", this); load_predefined_mtg_act[5]->setShortcut(Qt::Key_F6); load_predefined_mtg_act[6] = new QAction("Empty", this); load_predefined_mtg_act[6]->setShortcut(Qt::Key_F7); load_predefined_mtg_act[7] = new QAction("Empty", this); load_predefined_mtg_act[7]->setShortcut(Qt::Key_F8); load_predefined_mtg_act[8] = new QAction("Empty", this); load_predefined_mtg_act[8]->setShortcut(Qt::Key_F9); load_predefined_mtg_act[9] = new QAction("Empty", this); load_predefined_mtg_act[9]->setShortcut(Qt::Key_F10); load_predefined_mtg_act[10] = new QAction("Empty", this); load_predefined_mtg_act[10]->setShortcut(Qt::Key_F11); load_predefined_mtg_act[11] = new QAction("Empty", this); load_predefined_mtg_act[11]->setShortcut(Qt::Key_F12); load_predefined_mtg_group = new QActionGroup(this); for(i=0; i < MAXPREDEFINEDMONTAGES; i++) { load_predefined_mtg_group->addAction(load_predefined_mtg_act[i]); } connect(load_predefined_mtg_group, SIGNAL(triggered(QAction *)), this, SLOT(load_predefined_mtg(QAction *))); montagemenu = new QMenu(this); montagemenu->setTitle("&Montage"); montagemenu->addAction("View this montage", this, SLOT(show_this_montage())); montagemenu->addAction("View saved montages", this, SLOT(view_montage())); montagemenu->addAction("Save", this, SLOT(save_montage())); montagemenu->addAction("Load", this, SLOT(load_montage())); montagemenu->addSeparator(); montagemenu->addAction("Edit key-bindings for montages", this, SLOT(edit_predefined_montages())); montagemenu->addSeparator(); for(i=0; i < MAXPREDEFINEDMONTAGES; i++) { montagemenu->addAction(load_predefined_mtg_act[i]); } menubar->addMenu(montagemenu); // patternmenu = new QMenu(this); // patternmenu->setTitle("&Pattern"); // patternmenu->addAction("Search", this, SLOT(search_pattern())); // menubar->addMenu(patternmenu); toolsmenu = new QMenu(this); toolsmenu->setTitle("T&ools"); toolsmenu->addAction("Check EDF/BDF compatibility", this, SLOT(check_edf_compatibility())); toolsmenu->addSeparator(); toolsmenu->addAction("Header editor", this, SLOT(edit_header())); toolsmenu->addAction("Reduce signals, duration or samplerate", this, SLOT(reduce_signals())); toolsmenu->addAction("Remove duplicates in annotations", this, SLOT(edfplus_annotation_remove_duplicates())); toolsmenu->addSeparator(); toolsmenu->addAction("Import annotations/events", this, SLOT(import_annotations())); toolsmenu->addAction("Export annotations/events", this, SLOT(export_annotations())); toolsmenu->addAction("Export EDF/BDF to ASCII", this, SLOT(export_to_ascii())); toolsmenu->addAction("Export/Import ECG RR-interval", this, SLOT(export_ecg_rr_interval_to_ascii())); toolsmenu->addSeparator(); toolsmenu->addAction("Convert Nihon Kohden to EDF+", this, SLOT(nk2edf_converter())); toolsmenu->addAction("Convert ASCII to EDF/BDF", this, SLOT(convert_ascii_to_edf())); toolsmenu->addAction("Convert Manscan to EDF+", this, SLOT(convert_manscan_to_edf())); toolsmenu->addAction("Convert SCP ECG to EDF+", this, SLOT(convert_scpecg_to_edf())); toolsmenu->addAction("Convert MIT to EDF+", this, SLOT(convert_mit_to_edf())); toolsmenu->addAction("Convert Finometer to EDF", this, SLOT(convert_fino_to_edf())); toolsmenu->addAction("Convert Nexfin to EDF", this, SLOT(convert_nexfin_to_edf())); toolsmenu->addAction("Convert Emsa to EDF+", this, SLOT(convert_emsa_to_edf())); toolsmenu->addAction("Convert EDF+D to EDF+C", this, SLOT(edfd_converter())); toolsmenu->addAction("Convert Biosemi to BDF+", this, SLOT(biosemi2bdfplus_converter())); toolsmenu->addAction("Convert BDF to EDF", this, SLOT(bdf2edf_converter())); toolsmenu->addAction("Convert Unisens to EDF+", this, SLOT(unisens2edf_converter())); toolsmenu->addAction("Convert BI9800TL+3 to EDF", this, SLOT(BI98002edf_converter())); toolsmenu->addAction("Convert Wave to EDF", this, SLOT(convert_wave_to_edf())); toolsmenu->addAction("Convert Biox CB-1305-C to EDF", this, SLOT(convert_biox_to_edf())); toolsmenu->addAction("Convert FM Audio ECG to EDF", this, SLOT(convert_fm_audio_to_edf())); toolsmenu->addAction("Convert Binary/raw data to EDF", this, SLOT(convert_binary_to_edf())); toolsmenu->addSeparator(); toolsmenu->addAction("Options", this, SLOT(show_options_dialog())); menubar->addMenu(toolsmenu); menubar->addAction("S&ettings", this, SLOT(show_options_dialog())); former_page_Act = new QAction("<<", this); former_page_Act->setShortcut(QKeySequence::MoveToPreviousPage); connect(former_page_Act, SIGNAL(triggered()), this, SLOT(former_page())); menubar->addAction(former_page_Act); shift_page_left_Act = new QAction("<", this); shift_page_left_Act->setShortcut(QKeySequence::MoveToPreviousChar); connect(shift_page_left_Act, SIGNAL(triggered()), this, SLOT(shift_page_left())); menubar->addAction(shift_page_left_Act); playback_realtime_Act = new QAction("[play]", this); connect(playback_realtime_Act, SIGNAL(triggered()), this, SLOT(playback_realtime())); menubar->addAction(playback_realtime_Act); shift_page_right_Act = new QAction(">", this); shift_page_right_Act->setShortcut(QKeySequence::MoveToNextChar); connect(shift_page_right_Act, SIGNAL(triggered()), this, SLOT(shift_page_right())); menubar->addAction(shift_page_right_Act); next_page_Act = new QAction(">>", this); next_page_Act->setShortcut(QKeySequence::MoveToNextPage); connect(next_page_Act, SIGNAL(triggered()), this, SLOT(next_page())); menubar->addAction(next_page_Act); shift_page_up_Act = new QAction("^", this); shift_page_up_Act->setShortcut(QKeySequence::MoveToPreviousLine); connect(shift_page_up_Act, SIGNAL(triggered()), this, SLOT(shift_page_up())); menubar->addAction(shift_page_up_Act); shift_page_down_Act = new QAction("v", this); shift_page_down_Act->setShortcut(QKeySequence::MoveToNextLine); connect(shift_page_down_Act, SIGNAL(triggered()), this, SLOT(shift_page_down())); menubar->addAction(shift_page_down_Act); zoomback_Act = new QAction("zoomback", this); zoomback_Act->setShortcut(Qt::Key_Backspace); connect(zoomback_Act, SIGNAL(triggered()), this, SLOT(zoomback())); menubar->addAction(zoomback_Act); zoomforward_Act = new QAction("zoomforward", this); zoomforward_Act->setShortcut(Qt::Key_Insert); connect(zoomforward_Act, SIGNAL(triggered()), this, SLOT(forward())); menubar->addAction(zoomforward_Act); no_timesync_act = new QAction("no timelock", this); no_timesync_act->setCheckable(true); offset_timesync_act = new QAction("synchronize start of files (offset)", this); offset_timesync_act->setCheckable(true); absolut_timesync_act = new QAction("synchronize absolute time", this); absolut_timesync_act->setCheckable(true); user_def_sync_act = new QAction("user defined synchronizing", this); user_def_sync_act->setCheckable(true); timelock_act_group = new QActionGroup(this); timelock_act_group->addAction(no_timesync_act); timelock_act_group->addAction(offset_timesync_act); timelock_act_group->addAction(absolut_timesync_act); timelock_act_group->addAction(user_def_sync_act); absolut_timesync_act->setChecked(true); connect(timelock_act_group, SIGNAL(triggered(QAction *)), this, SLOT(set_timesync(QAction *))); sel_viewtime_act_group = new QActionGroup(this); connect(sel_viewtime_act_group, SIGNAL(triggered(QAction *)), this, SLOT(set_timesync_reference(QAction *))); timemenu = new QMenu(this); timemenu->setTitle("T&imesync"); timemenu->addAction("Go to start of file", this, SLOT(jump_to_start()), QKeySequence::MoveToStartOfDocument); timemenu->addAction("Go to end of file", this, SLOT(jump_to_end()), QKeySequence::MoveToEndOfDocument); timemenu->addAction("Jump to", this, SLOT(jump_to_dialog())); timemenu->addSeparator()->setText("Timelock"); timemenu->addAction(no_timesync_act); timemenu->addAction(offset_timesync_act); timemenu->addAction(absolut_timesync_act); timemenu->addAction(user_def_sync_act); timemenu->addSeparator(); timemenu->addAction("synchronize by crosshairs", this, SLOT(sync_by_crosshairs())); timemenu->addSeparator()->setText("Time reference"); menubar->addMenu(timemenu); windowmenu = new QMenu(this); windowmenu->setTitle("&Window"); windowmenu->addAction("Annotations", this, SLOT(show_annotations())); windowmenu->addAction("Annotation editor", this, SLOT(annotation_editor())); windowmenu->addAction("Power Spectrum", this, SLOT(show_spectrum_dock())); menubar->addMenu(windowmenu); helpmenu = new QMenu(this); helpmenu->setTitle("&Help"); #ifdef Q_OS_LINUX helpmenu->addAction("Manual", this, SLOT(show_help())); #endif #ifdef Q_OS_WIN32 helpmenu->addAction("Manual", this, SLOT(show_help())); #endif helpmenu->addAction("Keyboard shortcuts", this, SLOT(show_kb_shortcuts())); helpmenu->addAction("About EDFbrowser", this, SLOT(show_about_dialog())); helpmenu->addAction("Show splashscreen", this, SLOT(show_splashscreen())); menubar->addMenu(helpmenu); Escape_act = new QAction(this); Escape_act->setShortcut(Qt::Key_Escape); connect(Escape_act, SIGNAL(triggered()), this, SLOT(Escape_fun())); maincurve->addAction(Escape_act); positionslider = new QSlider(Qt::Horizontal); positionslider->setRange(0, 1000000); positionslider->setSingleStep(10000); positionslider->setPageStep(100000); video_pause_act = new QAction("Play", this); connect(video_pause_act, SIGNAL(triggered()), this, SLOT(video_player_toggle_pause())); video_pause_act->setToolTip("Play video"); video_stop_act = new QAction("Stop", this); connect(video_stop_act, SIGNAL(triggered()), this, SLOT(start_stop_video())); video_stop_act->setToolTip("Stop video"); slidertoolbar = new QToolBar(); slidertoolbar->setFloatable(false); slidertoolbar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); #ifdef Q_OS_LINUX slidertoolbar->addAction(video_stop_act); slidertoolbar->addAction(video_pause_act); #endif slidertoolbar->addWidget(positionslider); addToolBar(Qt::BottomToolBarArea, slidertoolbar); QObject::connect(positionslider, SIGNAL(valueChanged(int)), this, SLOT(slider_moved(int))); slidertoolbar->setEnabled(false); positionslider->blockSignals(true); files_open = 0; signalcomps = 0; sel_viewtime = 0; viewtime_sync = VIEWTIME_SYNCED_ABSOLUT; pagetime = 10 * TIME_DIMENSION; viewtime_string[0] = 0; pagetime_string[0] = 0; totalviewbufsize = 0; print_to_edf_active = 0; annot_editor_active = 0; annotations_edited = 0; viewbuf = NULL; for(i=0; i<MAXFILES; i++) { annotationlist[i] = NULL; annotations_dock[i] = NULL; } annotationlist_backup = NULL; zoomhistory = (struct zoomhistoryblock *)calloc(1, sizeof(struct zoomhistoryblock)); zoomhistory->history_size_tail = 0; zoomhistory->history_size_front = 0; for(i=0; i<MAXZOOMHISTORY; i++) { zoomhistory->pntr = 0; zoomhistory->pagetime[i] = 10 * TIME_DIMENSION; for(j=0; j<MAXFILES; j++) { zoomhistory->viewtime[i][j] = 0; } for(j=0; j<MAXSIGNALS; j++) { zoomhistory->voltpercm[i][j] = 70.0; zoomhistory->screen_offset[i][j] = 0.0; for(k=0; k<MAXSIGNALS; k++) { zoomhistory->sensitivity[i][j][k] = 0.0475; } } } path[0] = 0; recent_montagedir[0] = 0; recent_savedir[0] = 0; recent_opendir[0] = 0; montagepath[0] = 0; option_str[0] = 0; for(i=0; i<MAX_RECENTFILES; i++) { recent_file_path[i][0] = 0; recent_file_mtg_path[i][0] = 0; } for(i=0; i<MAXPREDEFINEDMONTAGES; i++) { predefined_mtg_path[i][0] = 0; } read_recent_file_settings(); for(i=0; i<MAXPREDEFINEDMONTAGES; i++) { if(predefined_mtg_path[i][0] != 0) { load_predefined_mtg_act[i]->setText(predefined_mtg_path[i]); } } annotationEditDock = new UI_AnnotationEditwindow(files_open, this); addDockWidget(Qt::BottomDockWidgetArea, annotationEditDock->dockedit, Qt::Horizontal); annotationEditDock->dockedit->hide(); for(i=0; i<MAXSPECTRUMDOCKS; i++) { spectrumdock[i] = new UI_SpectrumDockWindow(this); addDockWidget(Qt::TopDockWidgetArea, spectrumdock[i]->dock, Qt::Horizontal); spectrumdock[i]->dock->hide(); } setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); char tmp_str[MAX_PATH_LENGTH]; cmdlineargument = 0; cmdlineoption = 0; if(QCoreApplication::arguments().size()>1) { strcpy(tmp_str, QCoreApplication::arguments().at(1).toLocal8Bit().data()); if((strlen(tmp_str) > 2) && (!strncmp(tmp_str, "--", 2))) { strcpy(option_str, tmp_str); cmdlineoption++; } else { strcpy(path, tmp_str); cmdlineargument++; } if(QCoreApplication::arguments().size()>2) { strcpy(tmp_str, QCoreApplication::arguments().at(2).toLocal8Bit().data()); if(!cmdlineargument) { strcpy(path, tmp_str); } else { strcpy(montagepath, tmp_str); } cmdlineargument++; if(cmdlineargument == 1) { if(QCoreApplication::arguments().size()>3) { strcpy(montagepath, QCoreApplication::arguments().at(3).toLocal8Bit().data()); cmdlineargument++; } } } } showMaximized(); oldwindowheight = height(); if(cmdlineargument) { if(cmdlineoption) { if(!strcmp(option_str, "--stream")) { open_stream(); } } else { open_new_file(); } } if(QT_VERSION < MINIMUM_QT_VERSION) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "Qt version is too old"); messagewindow.exec(); } else { int v_nr; char v_str[32]; strncpy(v_str, qVersion(), 32); v_str[31] = 0; v_nr = 0x10000 * atoi(v_str); v_nr += 0x100 * atoi(v_str + 2); v_nr += atoi(v_str + 4); if(v_nr < MINIMUM_QT_VERSION) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "Qt version is too old"); messagewindow.exec(); } } pixmap = new QPixmap(":/images/splash.png"); splash = new QSplashScreen(this, *pixmap, Qt::WindowStaysOnTopHint); update_checker = NULL; if(check_for_updates) { update_checker = new Check_for_updates; } }
static inline bool analyseSegments( mbuf_t packet, /* input packet mbuf */ const UInt32 mbufsInCache, /* number of entries in segsPerMBuf[] */ const UInt32 segsPerMBuf[], /* segments required per mbuf */ SInt32 numSegs, /* total number of segments */ const UInt32 maxSegs) /* max controller segments per mbuf */ { mbuf_t newPacket; // output mbuf chain. mbuf_t out; // current output mbuf link. SInt32 outSize; // size of current output mbuf link. SInt32 outSegs; // segments for current output mbuf link. SInt32 doneSegs; // segments for output mbuf chain. SInt32 outLen; // remaining length of input buffer. mbuf_t in = packet; // save the original input packet pointer. UInt32 inIndex = 0; const uint32_t c_mlen = mbuf_get_mlen(); // Allocate a mbuf (non header mbuf) to begin the output mbuf chain. if(mbuf_get(MBUF_DONTWAIT, MT_DATA, &newPacket)) { ERROR_LOG("analyseSegments: MGET() 1 error\n"); return false; } /* Initialise outgoing packet controls */ out = newPacket; outSize = c_mlen; doneSegs = outSegs = outLen = 0; // numSegs stores the delta between the total and the max. For each // input mbuf consumed, we decrement numSegs. // numSegs -= maxSegs; // Loop through the input packet mbuf 'in' and construct a new mbuf chain // large enough to make (numSegs + doneSegs + outSegs) less than or // equal to zero. // do { uintptr_t vmo; outLen += mbuf_len(in); while (outLen > outSize) { // Oh dear the current outgoing length is too big. if (outSize != MCLBYTES) { // Current mbuf is not yet a cluster so promote, then // check for error. if(mbuf_mclget(MBUF_DONTWAIT, MT_DATA, &out) || !(mbuf_flags(out) & MBUF_EXT) ) { ERROR_LOG("analyseSegments: MCLGET() error\n"); goto bombAnalysis; } outSize = MCLBYTES; continue; } vmo = (uintptr_t)mbuf_data(out); mbuf_setlen(out, MCLBYTES); /* Fill in target copy size */ doneSegs += (round_page(vmo + MCLBYTES) - trunc_page(vmo)) / PAGE_SIZE; // If the number of segments of the output chain, plus // the segment for the mbuf we are about to allocate is greater // than maxSegs, then abort. // if (doneSegs + 1 > (int) maxSegs) { ERROR_LOG("analyseSegments: maxSegs limit 1 reached! %ld %ld\n", doneSegs, maxSegs); goto bombAnalysis; } mbuf_t tempmbuf; if(mbuf_get(MBUF_DONTWAIT, MT_DATA, &tempmbuf)) { ERROR_LOG("analyseSegments: MGET() error\n"); goto bombAnalysis; } mbuf_setnext(out, tempmbuf); out = tempmbuf; outSize = c_mlen; outLen -= MCLBYTES; } // Compute number of segment in current outgoing mbuf. vmo = (uintptr_t)mbuf_data(out); outSegs = ((SInt32)round_page(vmo + outLen) - (SInt32)trunc_page(vmo)) / (SInt32)PAGE_SIZE; if (doneSegs + outSegs > (int) maxSegs) { ERROR_LOG("analyseSegments: maxSegs limit 2 reached! %ld %ld %ld\n", doneSegs, outSegs, maxSegs); goto bombAnalysis; } // Get the number of segments in the current inbuf if (inIndex < mbufsInCache) numSegs -= segsPerMBuf[inIndex]; // Yeah, in cache else { // Hmm, we have to recompute from scratch. Copy code from genPhys. int thisLen = 0, mbufLen; vmo = (uintptr_t)mbuf_data(in); for (mbufLen = (SInt32)mbuf_len(in); mbufLen; mbufLen -= thisLen) { thisLen = MIN((SInt32)next_page(vmo), (SInt32)(vmo + mbufLen)) - (SInt32)vmo; vmo += thisLen; numSegs--; } } // Walk the incoming buffer on one. in = mbuf_next(in); inIndex++; // continue looping until the total number of segments has dropped // to an acceptable level, or if we ran out of mbuf links. } while (in && ((numSegs + doneSegs + outSegs) > 0)); if ( (int) (numSegs + doneSegs + outSegs) <= 0) { // success mbuf_setlen(out, outLen); // Set last mbuf with the remaining length. // The amount to copy is determine by the segment length in each // mbuf linked to newPacket. The sum can be smaller than // packet->pkthdr.len; // coalesceSegments(packet, newPacket); // The initial header mbuf is preserved, its length set to zero, and // linked to the new packet chain. // coalesceSegments() has already freed the mbufs that it coalesced into the newPacket chain. // It also hooked the remaining chain pointed to by "in" to the end of the newPacket chain. // All that remains is to set packet's len to 0 (to "free" the contents that coalesceSegments copied out) // and make it the head of the new chain. mbuf_setlen(packet , 0 ); mbuf_setnext(packet, newPacket); return true; } bombAnalysis: mbuf_freem(newPacket); return false; }
UInt32 IOMbufMemoryCursor::genPhysicalSegments(mbuf_t packet, void *vector, UInt32 maxSegs, bool doCoalesce) { bool doneCoalesce = false; if (!packet || !(mbuf_flags(packet) & MBUF_PKTHDR)) return 0; if (!maxSegs) { maxSegs = maxNumSegments; if (!maxSegs) return 0; } if ( mbuf_next(packet) == 0 ) { uintptr_t src; struct IOPhysicalSegment physSeg; /* * the packet consists of only 1 mbuf * so if the data buffer doesn't span a page boundary * we can take the simple way out */ src = (uintptr_t)mbuf_data(packet); if ( trunc_page(src) == trunc_page(src + mbuf_len(packet) - 1) ) { physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)src); if ( physSeg.location ) { physSeg.length = mbuf_len(packet); (*outSeg)(physSeg, vector, 0); return 1; } maxSegs = 1; if ( doCoalesce == false ) return 0; } } if ( doCoalesce == true && maxSegs == 1 ) { uintptr_t src; uintptr_t dst; mbuf_t m; mbuf_t mnext; mbuf_t out; UInt32 len = 0; struct IOPhysicalSegment physSeg; if ( mbuf_pkthdr_len(packet) > MCLBYTES ) return 0; m = packet; // Allocate a non-header mbuf + cluster. if (mbuf_getpacket( MBUF_DONTWAIT, &out )) return 0; mbuf_setflags( out, mbuf_flags( out ) & ~MBUF_PKTHDR ); dst = (uintptr_t)mbuf_data(out); do { src = (uintptr_t)mbuf_data(m); BCOPY( src, dst, mbuf_len(m) ); dst += mbuf_len(m); len += mbuf_len(m); } while ( (m = mbuf_next(m)) != 0 ); mbuf_setlen(out , len); dst = (uintptr_t)mbuf_data(out); physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)dst); if (!physSeg.location) { mbuf_free(out); return 0; } physSeg.length = mbuf_len(out); (*outSeg)(physSeg, vector, 0); m = mbuf_next(packet); while (m != 0) { mnext = mbuf_next(m); mbuf_free(m); m = mnext; } // The initial header mbuf is preserved, its length set to zero, // and linked to the new packet chain. mbuf_setlen(packet , 0); mbuf_setnext(packet , out); mbuf_setnext(out , 0); return 1; } // // Iterate over the mbuf, translating segments were allowed. When we // are not allowed to translate segments then accumulate segment // statistics up to kMBufDataCacheSize of mbufs. Finally // if we overflow our cache just count how many segments this // packet represents. // UInt32 segsPerMBuf[kMBufDataCacheSize]; tryAgain: UInt32 curMBufIndex = 0; UInt32 curSegIndex = 0; UInt32 lastSegCount = 0; mbuf_t m = packet; // For each mbuf in incoming packet. do { vm_size_t mbufLen, thisLen = 0; uintptr_t src; // Step through each segment in the current mbuf for (mbufLen = mbuf_len(m), src = (uintptr_t)mbuf_data(m); mbufLen; src += thisLen, mbufLen -= thisLen) { // If maxSegmentSize is atleast PAGE_SIZE, then // thisLen = MIN(next_page(src), src + mbufLen) - src; thisLen = MIN(mbufLen, maxSegmentSize); thisLen = MIN(next_page(src), src + thisLen) - src; // If room left then find the current segment addr and output if (curSegIndex < maxSegs) { struct IOPhysicalSegment physSeg; physSeg.location = (IOPhysicalAddress) mbuf_data_to_physical((char *)src); if ( physSeg.location == 0 ) { return doCoalesce ? genPhysicalSegments(packet, vector, 1, true) : 0; } physSeg.length = thisLen; (*outSeg)(physSeg, vector, curSegIndex); } // Count segments if we are coalescing. curSegIndex++; } // Cache the segment count data if room is available. if (curMBufIndex < kMBufDataCacheSize) { segsPerMBuf[curMBufIndex] = curSegIndex - lastSegCount; lastSegCount = curSegIndex; } // Move on to next imcoming mbuf curMBufIndex++; m = mbuf_next(m); } while (m); // If we finished cleanly return number of segments found if (curSegIndex <= maxSegs) return curSegIndex; if (!doCoalesce) return 0; // if !coalescing we've got a problem. // If we are coalescing and it is possible then attempt coalesce, if (!doneCoalesce && (UInt) mbuf_pkthdr_len(packet) <= maxSegs * maxSegmentSize) { // Hmm, we have to do some coalescing. bool analysisRet; analysisRet = analyseSegments(packet, MIN(curMBufIndex, kMBufDataCacheSize), segsPerMBuf, curSegIndex, maxSegs); if (analysisRet) { doneCoalesce = true; coalesceCount++; goto tryAgain; } } assert(!doneCoalesce); // Problem in Coalesce code. packetTooBigErrors++; return 0; }
void * initarm(void *arg, void *arg2) { #define next_chunk2(a,b) (((a) + (b)) &~ ((b)-1)) #define next_page(a) next_chunk2(a,PAGE_SIZE) struct pv_addr kernel_l1pt; struct pv_addr dpcpu; int loop, i; u_int l1pagetable; vm_offset_t freemempos; vm_offset_t freemem_pt; vm_offset_t afterkern; vm_offset_t freemem_after; vm_offset_t lastaddr; uint32_t memsize; set_cpufuncs(); /* NB: sets cputype */ lastaddr = fake_preload_metadata(); pcpu_init(pcpup, 0, sizeof(struct pcpu)); PCPU_SET(curthread, &thread0); /* Do basic tuning, hz etc */ init_param1(); /* * We allocate memory downwards from where we were loaded * by RedBoot; first the L1 page table, then NUM_KERNEL_PTS * entries in the L2 page table. Past that we re-align the * allocation boundary so later data structures (stacks, etc) * can be mapped with different attributes (write-back vs * write-through). Note this leaves a gap for expansion * (or might be repurposed). */ freemempos = KERNPHYSADDR; /* macros to simplify initial memory allocation */ #define alloc_pages(var, np) do { \ freemempos -= (np * PAGE_SIZE); \ (var) = freemempos; \ /* NB: this works because locore maps PA=VA */ \ memset((char *)(var), 0, ((np) * PAGE_SIZE)); \ } while (0) #define valloc_pages(var, np) do { \ alloc_pages((var).pv_pa, (np)); \ (var).pv_va = (var).pv_pa + (KERNVIRTADDR - KERNPHYSADDR); \ } while (0) /* force L1 page table alignment */ while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0) freemempos -= PAGE_SIZE; /* allocate contiguous L1 page table */ valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); /* now allocate L2 page tables; they are linked to L1 below */ for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) { valloc_pages(kernel_pt_table[loop], L2_TABLE_SIZE / PAGE_SIZE); } else { kernel_pt_table[loop].pv_pa = freemempos + (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) * L2_TABLE_SIZE_REAL; kernel_pt_table[loop].pv_va = kernel_pt_table[loop].pv_pa + (KERNVIRTADDR - KERNPHYSADDR); } } freemem_pt = freemempos; /* base of allocated pt's */ /* * Re-align allocation boundary so we can map the area * write-back instead of write-through for the stacks and * related structures allocated below. */ freemempos = PHYSADDR + 0x100000; /* * Allocate a page for the system page mapped to V0x00000000 * This page will just contain the system vectors and can be * shared by all processes. */ valloc_pages(systempage, 1); /* Allocate dynamic per-cpu area. */ valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE); dpcpu_init((void *)dpcpu.pv_va, 0); /* Allocate stacks for all modes */ valloc_pages(irqstack, IRQ_STACK_SIZE); valloc_pages(abtstack, ABT_STACK_SIZE); valloc_pages(undstack, UND_STACK_SIZE); valloc_pages(kernelstack, KSTACK_PAGES); alloc_pages(minidataclean.pv_pa, 1); valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE); #ifdef ARM_USE_SMALL_ALLOC freemempos -= PAGE_SIZE; freemem_pt = trunc_page(freemem_pt); freemem_after = freemempos - ((freemem_pt - (PHYSADDR + 0x100000)) / PAGE_SIZE) * sizeof(struct arm_small_page); arm_add_smallalloc_pages( (void *)(freemem_after + (KERNVIRTADDR - KERNPHYSADDR)), (void *)0xc0100000, freemem_pt - (PHYSADDR + 0x100000), 1); freemem_after -= ((freemem_after - (PHYSADDR + 0x1000)) / PAGE_SIZE) * sizeof(struct arm_small_page); arm_add_smallalloc_pages( (void *)(freemem_after + (KERNVIRTADDR - KERNPHYSADDR)), (void *)0xc0001000, trunc_page(freemem_after) - (PHYSADDR + 0x1000), 0); freemempos = trunc_page(freemem_after); freemempos -= PAGE_SIZE; #endif /* * Now construct the L1 page table. First map the L2 * page tables into the L1 so we can replace L1 mappings * later on if necessary */ l1pagetable = kernel_l1pt.pv_va; /* Map the L2 pages tables in the L1 page table */ pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH & ~(0x00100000 - 1), &kernel_pt_table[KERNEL_PT_SYS]); pmap_link_l2pt(l1pagetable, IXP425_IO_VBASE, &kernel_pt_table[KERNEL_PT_IO]); pmap_link_l2pt(l1pagetable, IXP425_MCU_VBASE, &kernel_pt_table[KERNEL_PT_IO + 1]); pmap_link_l2pt(l1pagetable, IXP425_PCI_MEM_VBASE, &kernel_pt_table[KERNEL_PT_IO + 2]); pmap_link_l2pt(l1pagetable, KERNBASE, &kernel_pt_table[KERNEL_PT_BEFOREKERN]); pmap_map_chunk(l1pagetable, KERNBASE, PHYSADDR, 0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); pmap_map_chunk(l1pagetable, KERNBASE + 0x100000, PHYSADDR + 0x100000, 0x100000, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); pmap_map_chunk(l1pagetable, KERNEL_TEXT_BASE, KERNEL_TEXT_PHYS, next_chunk2(((uint32_t)lastaddr) - KERNEL_TEXT_BASE, L1_S_SIZE), VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); freemem_after = next_page((int)lastaddr); afterkern = round_page(next_chunk2((vm_offset_t)lastaddr, L1_S_SIZE)); for (i = 0; i < KERNEL_PT_AFKERNEL_NUM; i++) { pmap_link_l2pt(l1pagetable, afterkern + i * 0x00100000, &kernel_pt_table[KERNEL_PT_AFKERNEL + i]); } pmap_map_entry(l1pagetable, afterkern, minidataclean.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); #ifdef ARM_USE_SMALL_ALLOC if ((freemem_after + 2 * PAGE_SIZE) <= afterkern) { arm_add_smallalloc_pages((void *)(freemem_after), (void*)(freemem_after + PAGE_SIZE), afterkern - (freemem_after + PAGE_SIZE), 0); } #endif /* Map the Mini-Data cache clean area. */ xscale_setup_minidata(l1pagetable, afterkern, minidataclean.pv_pa); /* Map the vector page. */ pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); if (cpu_is_ixp43x()) pmap_devmap_bootstrap(l1pagetable, ixp435_devmap); else pmap_devmap_bootstrap(l1pagetable, ixp425_devmap); /* * Give the XScale global cache clean code an appropriately * sized chunk of unmapped VA space starting at 0xff000000 * (our device mappings end before this address). */ xscale_cache_clean_addr = 0xff000000U; cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); setttb(kernel_l1pt.pv_pa); cpu_tlb_flushID(); cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)); /* * Pages were allocated during the secondary bootstrap for the * stacks for different CPU modes. * We must now set the r13 registers in the different CPU modes to * point to these stacks. * Since the ARM stacks use STMFD etc. we must set r13 to the top end * of the stack memory. */ set_stackptr(PSR_IRQ32_MODE, irqstack.pv_va + IRQ_STACK_SIZE*PAGE_SIZE); set_stackptr(PSR_ABT32_MODE, abtstack.pv_va + ABT_STACK_SIZE*PAGE_SIZE); set_stackptr(PSR_UND32_MODE, undstack.pv_va + UND_STACK_SIZE*PAGE_SIZE); /* * We must now clean the cache again.... * Cleaning may be done by reading new data to displace any * dirty data in the cache. This will have happened in setttb() * but since we are boot strapping the addresses used for the read * may have just been remapped and thus the cache could be out * of sync. A re-clean after the switch will cure this. * After booting there are no gross relocations of the kernel thus * this problem will not occur after initarm(). */ cpu_idcache_wbinv_all(); /* ready to setup the console (XXX move earlier if possible) */ cninit(); /* * Fetch the RAM size from the MCU registers. The * expansion bus was mapped above so we can now read 'em. */ if (cpu_is_ixp43x()) memsize = ixp435_ddram_size(); else memsize = ixp425_sdram_size(); physmem = memsize / PAGE_SIZE; /* Set stack for exception handlers */ data_abort_handler_address = (u_int)data_abort_handler; prefetch_abort_handler_address = (u_int)prefetch_abort_handler; undefined_handler_address = (u_int)undefinedinstruction_bounce; undefined_init(); proc_linkup0(&proc0, &thread0); thread0.td_kstack = kernelstack.pv_va; thread0.td_pcb = (struct pcb *) (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; thread0.td_pcb->pcb_flags = 0; thread0.td_frame = &proc0_tf; pcpup->pc_curpcb = thread0.td_pcb; arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL); pmap_curmaxkvaddr = afterkern + PAGE_SIZE; dump_avail[0] = PHYSADDR; dump_avail[1] = PHYSADDR + memsize; dump_avail[2] = 0; dump_avail[3] = 0; pmap_bootstrap(pmap_curmaxkvaddr, 0xd0000000, &kernel_l1pt); msgbufp = (void*)msgbufpv.pv_va; msgbufinit(msgbufp, msgbufsize); mutex_init(); i = 0; #ifdef ARM_USE_SMALL_ALLOC phys_avail[i++] = PHYSADDR; phys_avail[i++] = PHYSADDR + PAGE_SIZE; /* *XXX: Gross hack to get our * pages in the vm_page_array. */ #endif phys_avail[i++] = round_page(virtual_avail - KERNBASE + PHYSADDR); phys_avail[i++] = trunc_page(PHYSADDR + memsize - 1); phys_avail[i++] = 0; phys_avail[i] = 0; init_param2(physmem); kdb_init(); /* use static kernel environment if so configured */ if (envmode == 1) kern_envp = static_env; return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP - sizeof(struct pcb))); #undef next_page #undef next_chunk2 }
bool Oggeyman::get_next_frame(unsigned char *BGRAbuffer) { if (stream_done) return false; timer_update(); #ifdef ANDR //printf ("in get_next_frame: last_packet_time %12.2lf total_play_time %12.2lf \n", last_packet_time, total_play_time); // "foo" will be used as a tag in LogCat __android_log_print(ANDROID_LOG_INFO, "foo", "in get_next_frame: last_packet_time %12.2lf total_play_time %12.2lf \n", last_packet_time, total_play_time ); # endif if (last_packet_time > total_play_time) return false; // TODO: what's with this pp_level reduction business? // do we have a leftover packet from the last page? (and is it really theora?) #ifdef ANDR struct timespec time1,time2; clock_gettime(CLOCK_MONOTONIC, &time1); # endif bool packet_found = (next_packet(&ogg_theora_stream_state, &ogg_theora_packet) && theora_decode_header(&theo_info, &theo_comment, &ogg_theora_packet) >= 0); #ifdef ANDR clock_gettime(CLOCK_MONOTONIC, &time2); __android_log_print(ANDROID_LOG_INFO, "foo", "in get_next_frame: time to get next packet and decode header %6.2lf ms\n", (time2.tv_sec - time1.tv_sec)*1.e3 + (time2.tv_nsec - time1.tv_nsec)/1000.0f ); clock_gettime(CLOCK_MONOTONIC, &time1); # endif while (!packet_found && !stream_done) { bool is_theora_page = false; while (!stream_done && !is_theora_page) { stream_done = !next_page(); if (stream_done) continue; // submit the completed page to the streaming layer with ogg_stream_pagein. // check out the return value - it will be < 0 it the page does not correspond // to the stream whose state we are providing as the first argument is_theora_page = (ogg_stream_pagein(&ogg_theora_stream_state, ¤t_ogg_page) >= 0); } if (stream_done) continue; // Packets can span multiple pages, but next_packet, or rather ogg_stream_packetout, // should take care of that - not return packets until they are complete. packet_found = next_packet(&ogg_theora_stream_state, &ogg_theora_packet); } #ifdef ANDR clock_gettime(CLOCK_MONOTONIC, &time2); __android_log_print(ANDROID_LOG_INFO, "foo", "in get_next_frame: looping for next packet %6.2lf ms\n", (time2.tv_sec - time1.tv_sec)*1.e3 + (time2.tv_nsec - time1.tv_nsec)/1000.0f ); # endif if (packet_found) { #ifdef ANDR clock_gettime(CLOCK_MONOTONIC, &time1); # endif bool processing_ok = process_packet(BGRAbuffer); #ifdef ANDR clock_gettime(CLOCK_MONOTONIC, &time2); __android_log_print(ANDROID_LOG_INFO, "foo", "[Aug 2015] in get_next_frame: time to process the packet %6.2lf ms\n", (time2.tv_sec - time1.tv_sec)*1.e3 + (time2.tv_nsec - time1.tv_nsec)/1.e6 ); # endif return processing_ok; } return false; }
gboolean module_feedkey(int kv, int kvstate) { int lkv = tolower(kv); int shift_m=(kvstate&ShiftMask) > 0; // printf("%x %c %d\n", kv, kv, shift_m); if (kvstate & ControlMask) return FALSE; if (kvstate & (Mod1Mask|Mod4Mask|Mod5Mask)) return FALSE; if (kv==XK_Shift_L||kv==XK_Shift_R) { key_press_time = gmf.mf_current_time(); } if (!gmf.mf_tsin_pho_mode()) return 0; gboolean b_is_empty = is_empty(); switch (kv) { case XK_F7: if (is_empty()) return FALSE; state = STATE_ROMANJI; if (state_hira_kata != STATE_kata) state_hira_kata = STATE_kata; else state_hira_kata = STATE_hira; disp_input(); return TRUE; case XK_F8: if (is_empty()) return FALSE; state = STATE_ROMANJI; if (state_hira_kata != STATE_half_kata) state_hira_kata = STATE_half_kata; else state_hira_kata = STATE_hira; disp_input(); return TRUE; case XK_F11: system("kasumi &"); return TRUE; case XK_F12: system("kasumi -a &"); return TRUE; case XK_Up: if (b_is_empty) return FALSE; if (state==STATE_SELECT) { int N = page_N(); gmf.mf_tss->pho_menu_idx--; if (gmf.mf_tss->pho_menu_idx < 0) gmf.mf_tss->pho_menu_idx = N - 1; disp_select(); } return TRUE; case XK_Down: if (b_is_empty) return FALSE; if (state==STATE_CONVERT) { state = STATE_SELECT; gmf.mf_tss->sel_pho = TRUE; // puts("STATE_SELECT"); disp_select(); } else if (state==STATE_SELECT) { int N = page_N(); gmf.mf_tss->pho_menu_idx=(gmf.mf_tss->pho_menu_idx+1)% N; disp_select(); } return TRUE; case XK_Return: if (b_is_empty) return FALSE; if (state==STATE_SELECT) { if (select_idx(gmf.mf_tss->pho_menu_idx)) goto send; return TRUE; } send: return module_flush_input(); case XK_Escape: if (state==STATE_SELECT) { state = STATE_CONVERT; gmf.mf_tss->sel_pho = FALSE; gmf.mf_clear_sele(); } else if (state==STATE_CONVERT) goto rom; return FALSE; case XK_BackSpace: if (b_is_empty) { state_hira_kata = STATE_hira; return FALSE; } gmf.mf_hide_selections_win(); if (state&(STATE_CONVERT|STATE_SELECT)) { rom: // puts("romanji"); state = STATE_ROMANJI; cursor = jpN; segN = 0; disp_input(); return TRUE; } // puts("back"); if (keysN) { keysN--; keys[keysN]=0; } else if (jpN && cursor) { delete_jpstr(cursor-1); cursor--; } else return FALSE; disp_input(); auto_hide(); return TRUE; case XK_Delete: if (b_is_empty) return FALSE; if (state&STATE_ROMANJI) { if (keysN) return TRUE; delete_jpstr(cursor); disp_input(); } auto_hide(); return TRUE; case XK_Left: if (b_is_empty) return FALSE; if (state&STATE_ROMANJI) { if (keysN) keysN = 0; else { if (cursor) cursor--; } disp_input(); } else if (state&STATE_CONVERT) { if (shift_m) { anthy_resize_segment(ac, cursor, -1); load_seg(); } else { if (cursor) cursor--; } disp_convert(); } return TRUE; case XK_Right: if (b_is_empty) return FALSE; if (state&STATE_ROMANJI) { if (cursor < jpN) cursor++; disp_input(); } else if (state&STATE_CONVERT) { if (shift_m) { anthy_resize_segment(ac, cursor, 1); load_seg(); } else { if (cursor < segN-1) cursor++; } disp_convert(); } return TRUE; case XK_Home: if (b_is_empty) return FALSE; cursor = 0; if (state&STATE_ROMANJI) { disp_input(); } else if (state&STATE_CONVERT) { disp_convert(); } return TRUE; case XK_End: if (b_is_empty) return FALSE; if (state&STATE_ROMANJI) { cursor = jpN; disp_input(); } else if (state&STATE_CONVERT) { cursor = segN-1; disp_convert(); } return TRUE; case XK_Prior: if (state!=STATE_SELECT) return FALSE; prev_page(); return TRUE; case XK_Next: if (state!=STATE_SELECT) return FALSE; next_page(); return TRUE; case ' ': if (b_is_empty) return FALSE; goto lab1; default: if (state==STATE_SELECT) { char *pp; if ((pp=strchr(*gmf.mf_pho_selkey, lkv))) { int c=pp-*gmf.mf_pho_selkey; if (select_idx(c)) goto send; } return TRUE; } } // printf("kv %d\n", kv); if (!is_legal_char(kv)) return FALSE; kv = lkv; if (state==STATE_CONVERT && kv!=' ') { send_seg(); state = STATE_ROMANJI; } lab1: if (state==STATE_ROMANJI) { if (keysN < MAX_KEYS) keys[keysN++]=kv; keys[keysN]=0; parse_key(); disp_input(); } module_show_win(); if (kv==' ') { if (state==STATE_ROMANJI) { char tt[512]; clear_seg_label(); merge_jp(tt, TRUE); // dbg("tt %s %d\n", tt, strlen(tt)); anthy_set_string(ac, tt); load_seg(); } else if (state==STATE_CONVERT) { state = STATE_SELECT; gmf.mf_tss->sel_pho = TRUE; // puts("STATE_SELECT"); disp_select(); } else if (state==STATE_SELECT) { next_page(); } } return TRUE; }
void Chapter::download() { sf::Http web(Manga::MangaHost); sf::Http::Request request(m_uri); sf::Http::Response response = web.sendRequest(request); sf::Http::Response::Status status = response.getStatus(); if (status == sf::Http::Response::Ok) { std::string body(response.getBody()); //Erase all of the \n eraseN(body); if (testing) { char html_file[300]; sprintf(html_file, "test/chapter_%u_page1.html", m_num_chapter); FILE* f = fopen(html_file, "w"); fwrite(body.c_str(), sizeof(char), body.size(), f); fclose(f); std::cout<<"Html page output to file: "<<html_file<<"\n"; } sscanf(getParse(body, Manga::parseChapterPages).c_str(), "%u", &m_pages); if (testing) std::cout<<"number of pages for chapter "<<m_num_chapter<<" parsed: "<<m_pages<<"\n"; //Clean images for (std::vector<Image*>::iterator it(m_images.begin()); it != m_images.end(); ++it) delete *it; m_images.resize(m_pages); for (unsigned int i(0); i<m_images.size(); ++i) m_images[i] = new Image; //we ad the fisrt image m_images[0]->setUrl(getParse(body, Manga::parsePageImg)); m_images[0]->setDir(m_dir); char filename[300]; sprintf(filename, "%s %u-1", m_manga->m_name.c_str(), m_num_chapter); m_images[0]->setFileName(filename); if (!testing) { m_images[0]->thDownload(); std::cout<<"Image 1/"<<m_images.size()<<" found.\n"; } std::string next_page(getParse(body, Manga::parsePageNext)); switch (Manga::mangaPath) { case URL_uri: break; case URL_absolute: next_page = getUri(next_page); break; case URL_relative: next_page = getWorkingDirectory(m_uri) + next_page; break; default: break; } if (testing) std::cout<<"Image 1 parsed: "<<m_images[0]->getUrl()<<"\nNext page parsed (Uri format): "<<next_page<<"\n"; for (unsigned int i(1); i<m_images.size(); ++i) { request.setUri(next_page); response = web.sendRequest(request); status = response.getStatus(); if (status == sf::Http::Response::Ok) { std::string body(response.getBody()); //Erase all of the \n eraseN(body); if (testing && i == 1) { char html_file[300]; sprintf(html_file, "test/chapter_%u_other_page.html", m_num_chapter); FILE* f = fopen(html_file, "w"); fwrite(body.c_str(), sizeof(char), body.size(), f); fclose(f); std::cout<<"Html page output to file: "<<html_file<<"\n"; } m_images[i]->setUrl(getParse(body, Manga::parsePageImg)); m_images[i]->setDir(m_dir); sprintf(filename, "%s %u-%u", m_manga->m_name.c_str(), m_num_chapter, i+1); m_images[i]->setFileName(filename); if (!testing) { m_images[i]->thDownload(); std::cout<<"Image "<<i+1<<"/"<<m_images.size()<<" found.\n"; } next_page = getParse(body, Manga::parsePageNext); switch (Manga::mangaPath) { case URL_uri: break; case URL_absolute: next_page = getUri(next_page); break; case URL_relative: next_page = getWorkingDirectory(m_uri) + next_page; break; default: break; } if (testing) std::cout<<"Image "<<i+1<<" parsed: "<<m_images[i]->getUrl()<<"\nNext page parsed: "<<next_page<<"\n"; } else std::cout<<"Error getting page: "<<status<<"\n"; } //std::cout<<"img:"<<getParse(body, Manga::parsePageImg)<<" next page: "<<getParse(body, Manga::parsePageNext)<<"\n"; //Download imgs //for (int i=0; i<1; ++i) m_images[i]->thDownload(); } else std::cout<<"Error checking chapter: "<<status<<"\n"; }