/* * GraphApp server for the Blue environment * ---------------------------------------- * Copyright (c) 1998 Loki (Version 2) * * This program implements a graphics server based on the * GraphApp library. You will need to download and install * GraphApp on your system, and get it working before you * proceed. * * Once GraphApp is working, you can compile this program. * You may have to edit the Makefile in this directory to * get things working properly. * * You will also need the GraphApp.bp project found in Loki's * directory, under /usr/pgrad/loki/blue/GraphApp.bp. */ #include #include #include #include /* * Server global variables: */ int USESTORE = 1; /* use backing store bitmap? */ #define DEBUG 1 /* produce debugging version? */ #if DEBUG #define REPORT printf #else #define REPORT // #endif #define MAXCHARS 256 #define MAXIMAGES 128 FILE *data = NULL; char *dir = ".graphapp"; char *datapath = "data"; char *status = "status"; window win = NULL; bitmap store = NULL; image images [MAXIMAGES]; int imgnum = 0; long total_wait = 0L; /* * Function prototypes: */ void create_window(void); void handle_events(void); void handle_one_event(void); void handle_error(char *str); void handle_blank(void); void handle_exitapp(void); void handle_hide(void); void handle_show(void); void handle_clear(void); void handle_drawall(void); void handle_delay(char *str); void handle_setrgb(char *str); void handle_drawstr(char *str); void handle_drawpoint(char *str); void handle_drawline(char *str); void handle_drawrect(char *str); void handle_fillrect(char *str); void handle_drawellipse(char *str); void handle_fillellipse(char *str); void handle_loadimage(char *str); void handle_drawimage(char *str); /* * Graphics server: */ int main(void) { char *home = NULL; char str[MAXCHARS]; /* find the home directory, exit if there is none */ if ((home = getenv("HOME")) == NULL) exit(1); /* create the directory if it isn't there */ sprintf(str, "mkdir -p %s/%s", home, dir); REPORT("%-20s\t%s/%s\n", "Creating:", home, dir); system(str); /* create the pipe path name */ sprintf(str, "%s/%s/%s", home, dir, datapath); datapath = strdup(str); /* create the halt-file name */ sprintf(str, "%s/%s/%s", home, dir, status); status = strdup(str); /* remove any old named pipe */ sprintf(str, "rm -f %s", datapath); REPORT("%-20s\t%s\n", "Removing:", datapath); system(str); /* create a new named pipe */ /* sprintf(str, "mkfifo %s", datapath); REPORT("%-20s\t %s\n", "Creating:", datapath); system(str); */ /* open the pipe for writing */ REPORT("%-20s\t%s\n", "Opening to write:", datapath); if ((data = fopen(datapath, "w")) == NULL) exit(2); REPORT("%-20s\t%s\n", "Write newline:", datapath); fprintf(data, "\n"); REPORT("%-20s\t%s\n", "Closing:", datapath); fclose(data); /* open the pipe for reading */ REPORT("%-20s\t%s\n", "Opening to read:", datapath); if ((data = fopen(datapath, "r")) == NULL) exit(2); /* create a graphics window */ create_window(); /* handle all events */ REPORT("Handling all events ...\n"); handle_events(); return 0; } /* * Run commands: */ int run_command(char *str) { int keep = 1; if (!strcmp(str, "")) {handle_blank(); keep=0; } else if (!strncmp(str, "exit", 4)) {handle_exitapp(); keep=0; } else if (!strncmp(str, "hide", 4)) {handle_hide(); keep=0; } else if (!strncmp(str, "show", 4)) {handle_show(); keep=0; } else if (!strncmp(str, "clear", 5)) {handle_clear(); keep=0; } else if (!strncmp(str, "delay", 5)) {handle_delay(str); } else if (!strncmp(str, "setrgb", 6)) {handle_setrgb(str); } else if (!strncmp(str, "drawall", 7)) {handle_drawall(); keep=0; } else if (!strncmp(str, "drawstr", 7)) {handle_drawstr(str); } else if (!strncmp(str, "drawline", 8)) {handle_drawline(str); } else if (!strncmp(str, "drawrect", 8)) {handle_drawrect(str); } else if (!strncmp(str, "fillrect", 8)) {handle_fillrect(str); } else if (!strncmp(str, "drawpoint", 9)) {handle_drawpoint(str); } else if (!strncmp(str, "drawellip", 9)) {handle_drawellipse(str); } else if (!strncmp(str, "fillellip", 9)) {handle_fillellipse(str); } else if (!strncmp(str, "loadimage", 9)) {handle_loadimage(str); keep=0; } else if (!strncmp(str, "drawimage", 9)) {handle_drawimage(str); } else { handle_error(str); keep=0; } return keep; } /* * Handle events: */ void handle_events(void) { while(1) { while (isvisible(win) && peekevent()) doevent(); handle_one_event(); } } void handle_one_event(void) { char str[MAXCHARS]; char *result; int length; // REPORT("Reading data file ...\n"); result = fgets(str, MAXCHARS-2, data); if (result == NULL) { handle_blank(); return; } else total_wait = 0L; length = strlen(str); if (str[length-1] == '\n') str[length-1] = '\0'; // REPORT("Message received: %s\n", str); run_command(str); drawall(); } /* * Create the window and a backing store bitmap: */ void resize_window(window w, rect r) { bitmap newstore = NULL; int h; h = getheight(SystemFont); if (store) { newstore = newbitmap(r.width, r.height, 0); bitblt(newstore, store, pt(0,0), getrect(store), S); del(store); store = newstore; } } void update_window(void) { if (isvisible(win)) { if (store) bitblt(win, store, pt(0,0), getrect(store), S); } } void redraw_window(window w, rect r) { if (store) update_window(); } void close_window(window w) { handle_exitapp(); } void create_window(void) { rect r; int h; initapp(0,0); h = getheight(SystemFont); r = rect(30,30,600,400); REPORT("Creating a window\n"); win = newwindow("Blue GraphApp Server", r, StandardWindow); if (USESTORE) { REPORT("Creating a backing store bitmap\n"); store = newbitmap(r.width, r.height, 0); } setredraw(win, redraw_window); setresize(win, resize_window); setclose(win, close_window); REPORT("Showing the window\n"); show(win); } /* * Special events: */ void handle_error(char *str) { char error_string[MAXCHARS]; sprintf(error_string, "Error: %s\n", str); } void handle_blank(void) { long wait_time; if (total_wait >= 5000) { /* if more than 5 seconds have elapsed */ wait_time = 1500; /* wait in 1.5 second blocks */ total_wait = 5000; } else { wait_time = 500; /* otherwise check every 500 millisecs */ total_wait = total_wait + wait_time; } delay(wait_time); } /* * Handle various kinds of events: */ void handle_exitapp(void) { REPORT("Closing graphics window.\n"); remove(datapath); exitapp(); } void handle_hide(void) { hide(win); } void handle_show(void) { show(win); } void handle_drawall(void) { drawall(); } void handle_clear(void) { drawing dest; drawing prev; rgb old; if (store) dest = store; else dest = win; prev = currentdrawing(); drawto(dest); old = currentrgb(); setrgb(White); fillrect(getrect(dest)); setrgb(old); drawto(prev); update_window(); } void handle_delay(char *str) { int msec; while (!isspace(*str)) str++; sscanf(str, "%d", &msec); delay(msec); } void handle_setrgb(char *str) { int r, g, b; while (!isspace(*str)) str++; sscanf(str, "%d %d %d", &r, &g, &b); if (store) { drawto(store); setrgb(rgb(r,g,b)); } drawto(win); setrgb(rgb(r,g,b)); } void handle_drawstr(char *str) { int x, y; while (!isspace(*str)) str++; /* skip command */ sscanf(str, "%d %d", &x, &y); while (isspace(*str)) str++; /* skip space */ while (!isspace(*str)) str++; /* skip x */ while (isspace(*str)) str++; /* skip space */ while (!isspace(*str)) str++; /* skip y */ while (isspace(*str)) str++; /* skip spaces */ if (store) { drawto(store); drawstr(pt(x,y), str); } if (isvisible(win)) { drawto(win); drawstr(pt(x,y), str); } } void handle_drawpoint(char *str) { int x, y; while (!isspace(*str)) str++; sscanf(str, "%d %d", &x, &y); if (store) { drawto(store); drawpoint(pt(x,y)); } if (isvisible(win)) { drawto(win); drawpoint(pt(x,y)); } } void handle_drawline(char *str) { int x1, y1, x2, y2; while (!isspace(*str)) str++; sscanf(str, "%d %d %d %d", &x1, &y1, &x2, &y2); if (store) { drawto(store); drawline(pt(x1,y1),pt(x2,y2)); } if (isvisible(win)) { drawto(win); drawline(pt(x1,y1),pt(x2,y2)); } } void handle_drawrect(char *str) { int x, y, w, h; while (!isspace(*str)) str++; sscanf(str, "%d %d %d %d", &x, &y, &w, &h); if (store) { drawto(store); drawrect(rect(x,y,w,h)); } if (isvisible(win)) { drawto(win); drawrect(rect(x,y,w,h)); } } void handle_fillrect(char *str) { int x, y, w, h; while (!isspace(*str)) str++; sscanf(str, "%d %d %d %d", &x, &y, &w, &h); if (store) { drawto(store); fillrect(rect(x,y,w,h)); } if (isvisible(win)) { drawto(win); fillrect(rect(x,y,w,h)); } } void handle_drawellipse(char *str) { int x, y, w, h; while (!isspace(*str)) str++; sscanf(str, "%d %d %d %d", &x, &y, &w, &h); if (store) { drawto(store); drawellipse(rect(x,y,w,h)); } if (isvisible(win)) { drawto(win); drawellipse(rect(x,y,w,h)); } } void handle_fillellipse(char *str) { int x, y, w, h; while (!isspace(*str)) str++; sscanf(str, "%d %d %d %d", &x, &y, &w, &h); if (store) { drawto(store); fillellipse(rect(x,y,w,h)); } if (isvisible(win)) { drawto(win); fillellipse(rect(x,y,w,h)); } } void handle_loadimage(char *str) { image img = NULL; while (!isspace(*str)) str++; while (isspace(*str)) str++; img = loadimage(str); imgnum = imgnum + 1; if (imgnum >= MAXIMAGES) { handle_error("Not enough memory to store another image."); return; } if (! img) { handle_error("Could not open that image file."); return; } images[imgnum] = img; } void handle_drawimage(char *str) { image img; rect r; int num, x, y; while (!isspace(*str)) str++; sscanf(str, "%d %d %d", &num, &x, &y); if (num < 0) { handle_error("Image id number is less than zero!"); return; } if (num > imgnum) { handle_error("Image id number is not a legal value!"); return; } img = images[num]; r = getrect(img); if (! img) { handle_error("That image failed to load properly."); return; } if (store) { drawto(store); drawimage(img, rect(x,y,r.width,r.height), r); update_window(); } else if (isvisible(win)) { drawto(win); drawimage(img, rect(x,y,r.width,r.height), r); } }