/* * Copyright (c) 2004, Adam Dunkels. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file is part of the Contiki operating system. * * Author: Adam Dunkels * * $Id: editor.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $ */ #define EDITOR_CONF_WIDTH 32 #define EDITOR_CONF_HEIGHT 16 #define EDITOR_CONF_MAX_FILENAME_LEN 16 #include "contiki.h" #include "contiki-lib.h" #include "ctk/ctk.h" #include "cfs/cfs.h" #include "lib/ctk-filedialog.h" #define ISO_nl 0x0a PROCESS(editor_process, "Editor"); static struct ctk_window window; #define LINE_LEN 60 #define NUM_LINES EDITOR_CONF_HEIGHT struct line { struct line *next, *prev; char text[LINE_LEN]; }; MEMB(linesmem, struct line, NUM_LINES); static struct line *lines; static struct { unsigned char x, y; struct ctk_label labels[NUM_LINES]; } editor_state; static struct ctk_button openbutton = {CTK_BUTTON(0, 0, 4, "Open")}; static char statustext[EDITOR_CONF_WIDTH + 1]; static struct ctk_label statuslabel = {CTK_LABEL(0, EDITOR_CONF_HEIGHT + 2, EDITOR_CONF_WIDTH, 1, statustext)}; static struct ctk_menu menu; static unsigned char menuitem_new, menuitem_open, menuitem_save; static char filename[EDITOR_CONF_MAX_FILENAME_LEN]; static struct ctk_filedialog_state filedialog; enum { OPEN_EVENT }; /*---------------------------------------------------------------------------*/ static void show_statustext(char *text1, char *text2) { int len; len = strlen(text1); if(len < sizeof(statustext)) { strncpy(statustext, text1, sizeof(statustext)); strncpy(statustext + len, text2, sizeof(statustext) - len); CTK_WIDGET_REDRAW(&statuslabel); } } /*---------------------------------------------------------------------------*/ static void editor_start(void) { unsigned char i; register struct ctk_label *label; struct line *l, *m; m = NULL; for(i = 0; i < NUM_LINES; ++i) { label = &editor_state.labels[i]; l = (struct line *)memb_alloc(&linesmem); if(l != NULL) { l->next = NULL; l->prev = m; if(m == NULL) { /* First line */ lines = l; } else { m->next = l; } CTK_LABEL_NEW(label, 0, i + 1, EDITOR_CONF_WIDTH, 1, l->text); CTK_WIDGET_SET_FLAG(label, CTK_WIDGET_FLAG_MONOSPACE); CTK_WIDGET_ADD(&window, label); } m = l; } } /*---------------------------------------------------------------------------*/ static void editor_eventhandler(process_event_t ev, process_data_t data) { char *textptr, *textptr2; unsigned char len; if(ev == ctk_signal_keypress) { /* CTK_WIDGET_FOCUS(t->label.window, &t->label);*/ textptr = &(editor_state.labels[editor_state.y].text[editor_state.x]); *textptr &= 0x7f; CTK_WIDGET_REDRAW(&(editor_state.labels[editor_state.y])); switch((ctk_arch_key_t)data) { case CH_CURS_DOWN: ++editor_state.y; if(editor_state.y >= EDITOR_CONF_HEIGHT) { editor_state.y = EDITOR_CONF_HEIGHT - 1; } break; case CH_CURS_UP: if(editor_state.y > 0) { --editor_state.y; } break; case CH_CURS_RIGHT: if(editor_state.x < strlen(editor_state.labels[editor_state.y].text)) { ++editor_state.x; } break; case CH_CURS_LEFT: if(editor_state.x > 0) { --editor_state.x; } else { if(editor_state.y > 0) { --editor_state.y; editor_state.x = strlen(editor_state.labels[editor_state.y].text); } } break; case CH_ENTER: editor_state.x = 0; ++editor_state.y; if(editor_state.y >= EDITOR_CONF_HEIGHT) { editor_state.y = EDITOR_CONF_HEIGHT - 1; } break; case CH_DEL: /* len = t->label.w - t->xpos; if(t->xpos > 0 && len > 0) { strncpy(textptr - 1, textptr, len); *(textptr + len - 1) = 0; --t->xpos; }*/ break; default: len = EDITOR_CONF_WIDTH - editor_state.x; if(len > 0) { textptr2 = textptr + len - 1; while(textptr2 + 1 > textptr) { *(textptr2 + 1) = *textptr2; --textptr2; } *textptr = (char)data; ++editor_state.x; if(editor_state.x == EDITOR_CONF_WIDTH) { editor_state.x = 0; if(editor_state.y < EDITOR_CONF_HEIGHT - 1) { ++editor_state.y; } } } break; } textptr = &(editor_state.labels[editor_state.y].text[editor_state.x]); *textptr |= 0x80; CTK_WIDGET_REDRAW(&(editor_state.labels[editor_state.y])); /* } else if(s == ctk_signal_widget_activate && data == (process_data_t)t) { textptr = &(t->label.text[t->ypos * t->label.w + t->xpos]); *textptr &= 0x7f; t->xpos = 0; if(t->ypos < t->label.h - 1) { ++t->ypos; } textptr = &(t->label.text[t->ypos * t->label.w + t->xpos]); *textptr |= 0x80; CTK_WIDGET_REDRAW(&t->label);*/ } } /*---------------------------------------------------------------------------*/ static void open_file(char *name) { int fd; struct line *l; char line[LINE_LEN]; char *cptr; int i, len, clen; fd = cfs_open(name, 0); if(fd < 0) { show_statustext("Could not open file ", name); return; } l = lines; cptr = l->text; clen = LINE_LEN; do { /* Read a portion of the input file */ len = cfs_read(fd, line, LINE_LEN); /* Split the input into lines. */ for(i = 0; i < len; ++i) { if(line[i] == ISO_nl || clen == 0) { *cptr = 0; l = l->next; if(l != NULL) { cptr = l->text; clen = LINE_LEN; } else { len = -1; break; } } else { *cptr++ = line[i]; --clen; } } } while(len > 0); cfs_close(fd); } /*---------------------------------------------------------------------------*/ static void quit(void) { ctk_window_close(&window); process_exit(&editor_process); LOADER_UNLOAD(); } /*---------------------------------------------------------------------------*/ PROCESS_THREAD(editor_process, ev, data) { PROCESS_BEGIN(); memb_init(&linesmem); ctk_window_new(&window, EDITOR_CONF_WIDTH + 2, EDITOR_CONF_HEIGHT + 3, "Editor"); CTK_WIDGET_ADD(&window, &openbutton); CTK_WIDGET_ADD(&window, &statuslabel); CTK_WIDGET_FOCUS(&window, &openbutton); editor_start(); ctk_window_open(&window); while(1) { PROCESS_WAIT_EVENT(); if(ctk_filedialog_eventhandler(&filedialog, ev, data)) { } else { if(ev == PROCESS_EVENT_EXIT) { quit(); } else if(ev == OPEN_EVENT) { /* printf("Open file '%s'\n", (char *)data);*/ open_file((char *)data); ctk_window_redraw(&window); } else { if(ev == ctk_signal_window_close && data == (process_data_t)&window) { quit(); } else if(ev == ctk_signal_widget_activate) { if(data == (process_data_t)&openbutton) { ctk_filedialog_open(&filedialog, "Open", OPEN_EVENT); } } else { editor_eventhandler(ev, data); } } } } PROCESS_END(); } /*---------------------------------------------------------------------------*/ /*LOADER_INIT_FUNC(editor_init, arg) { arg_free(arg); id = ek_start(&p); }*/ /*---------------------------------------------------------------------------*/