#include #include #include #include #include #include #include #include #include #include #include #ifdef bool #undef bool #endif typedef short bool; BASEPAGE *master = (BASEPAGE *) 0; char *master_var; #define kByte * 1024L extern long _stksize = 2 kByte; extern char *_ltoa(); extern long modul(const char *); extern long set_x(const char *); extern long set_y(const char *); extern long log_x(const char *); extern long log_y(const char *); typedef struct { char *master_name; short function_type; long (*function_entry)(const char *cmdline); } func; func module_entries[] = { { "SCREEN", 0, modul } }; #define _MODUL_MAGIC 0x5343524EL /* 'SCRN' */ #define _MMX_MAGIC 0x4D4D5845L /* 'MMXE' */ struct head { char *module_description; short module_version; short number_of_functions; func *jump_table; long module_magic; /* 'SCRN' */ long xbra_magic; /* 'XBRA' */ long mmx_magic; /* 'MMXE' */ struct head *next; short jump; long (*this)(); } module_header = { " Master-Module-eXtension for screen setting\r\n" "\n" " Usage | Explanation\r\n" " ------------------------+--------------------------\r\n" " screen | show screen parameters\r\n" " screen help | print this help message\r\n" " screen min_x | set minimal screen column\r\n" " screen min_y | set minimal screen line\r\n" " screen max_x | set maximal screen column\r\n" " screen max_y | set maximal screen line\r\n", 1, 1, module_entries, _MODUL_MAGIC, _XBRA_MAGIC, _MMX_MAGIC, (struct head *) 0, _JMP_OPCODE, (long (*)()) 0 }; #define WRITE(f,text) write(f, text, strlen(text)) static short initial_max_x; static short initial_max_y; static bool is_color; static short screen_x_offset = 0; static short screen_y_offset = 0; static short font_x_offset; static short font_y_offset; long set_x(const char *cmd) { short x; short old_x; old_x = V_CEL_MX; if(!*cmd) { return(old_x); } else { x = atoi(cmd); x = min(initial_max_x - screen_x_offset,x); x = max(0,x); V_CEL_MX = x; return(0); } } long set_y(const char *cmd) { short y; short old_y; old_y = V_CEL_MY; if(!*cmd) { return(old_y); } else { y = atoi(cmd); y = min(initial_max_y - screen_y_offset,y); y = min(initial_max_y - (screen_x_offset != 0),y); y = max(0,y); V_CEL_MY = y; return(0); } } long log_x(const char *cmd) { short x; short old_x; old_x = screen_x_offset; if(!*cmd) { return(old_x); } else { is_color = (VPLANES > 1); x = atoi(cmd); if(is_color && (x & 1)) WRITE(2,"Sorry only even values allowed on color screens\r\n"); x = (x + is_color) & ~is_color; x = min(x,initial_max_x & ~is_color); x = max(x,0); screen_x_offset = x; old_x = min(V_CEL_MX + old_x,initial_max_x) - x; V_CEL_MX = max(old_x,0); V_CEL_MY = min(V_CEL_MY,initial_max_y - (screen_x_offset != 0)); write(2, "\33H", 2); Setscreen(Physbase()+screen_y_offset*VWRAP*font_y_offset+screen_x_offset*font_x_offset,-1,-1); Vsync(); return(0); } } long log_y(const char *cmd) { short y; short old_y; old_y = screen_y_offset; if(!*cmd) { return(old_y); } else { y = atoi(cmd); y = min(y,initial_max_y); y = max(y,0); V_CEL_MY = min(V_CEL_MY + old_y,initial_max_y - (screen_x_offset != 0)) - y; screen_y_offset = y; write(2, "\33H", 2); Setscreen(Physbase()+screen_y_offset*VWRAP*font_y_offset+screen_x_offset*font_x_offset,-1,-1); Vsync(); return(0); } } long modul(const char *cmdlin) { char output[30]; if(!*cmdlin) { _ltoa(log_x(""), output, 10); WRITE(1,output); write(1, " ", 1); _ltoa(log_y(""), output, 10); WRITE(1,output); write(1, " ", 1); _ltoa(set_x(""), output, 10); WRITE(1,output); write(1, " ", 1); _ltoa(set_y(""), output, 10); WRITE(1,output); write(1, "\r\n", 2); return(0); } else if(!strcmp(cmdlin,"help")) { WRITE(1,module_header.module_description); } else if(cmdlin[5] && cmdlin[5] != ' ') { return(1); } else if(!strncmp(cmdlin,"min_x",5)) { log_x(cmdlin+5); } else if(!strncmp(cmdlin,"min_y",5)) { log_y(cmdlin+5); } else if(!strncmp(cmdlin,"max_x",5)) { set_x(cmdlin+5); } else if(!strncmp(cmdlin,"max_y",5)) { set_y(cmdlin+5); } strcpy(output,"setenv LINES "); _ltoa(V_CEL_MY+1, output+13, 10); WRITE(2,output); system(output); return(0); } struct head *current; static long my_cookies[16] = { _MODUL_MAGIC, (long) &module_header, 0L, 8L }; void remove_cookies() { set_sysvar_to_long(_p_cookies,0L); } void remove_cookie() { long *cp; if(cp = (long *) get_sysvar(_p_cookies)) { while(*cp && *cp != _MODUL_MAGIC) cp += 2; while(*cp) { cp[0] = cp[2]; cp[1] = cp[3]; cp += 2; } } } void install_cookie(int resident) { long *cp; long cookies_used = 0; long tmp; initial_max_x = V_CEL_MX; initial_max_y = V_CEL_MY; font_x_offset = VWRAP / (initial_max_x + 1); font_y_offset = (V_Y_MAX + 1) / (initial_max_y + 1); if(!(cp = (long *) get_sysvar(_p_cookies))) { if(!resident) { write(2, "Unable to install cookie!\r\n", 27); exit(1); } signal(SIGRESET,remove_cookies); set_sysvar_to_long(_p_cookies,(long)(cp = my_cookies)); } while(*cp && *cp != _MODUL_MAGIC) { cp += 2; cookies_used++; } if(*cp) { current = (struct head *) cp[1]; return; } if(!(cp[1] - cookies_used - 1)) { write(2, "No room for cookie!\r\n", 21); exit(1); } *cp++ = _MODUL_MAGIC; tmp = *cp; *cp++ = (long) (current = &module_header); *cp++ = 0L; *cp = tmp; return; } void install_module(int resident, char *firstcmd) { long keep; install_cookie(resident); if(master) { strcpy(master_var, "Master-Module "); _ltoa(current, master_var+14, 10); } if(current != &module_header) { (*(current->jump_table[0].function_entry))(firstcmd); exit(0); } if(!*firstcmd) modul("help"); else modul(firstcmd); if(!resident) return; keep = _base->p_tlen + _base->p_dlen + _base->p_blen + sizeof(BASEPAGE); _base = _base->p_parent; Ptermres(keep, 0); } void remove_module() { remove_cookie(); } void usage(char *prog) { write(2, "Usage: [ module ] ", 18); WRITE(2, prog); write(2, " [ ]\r\n", 12); exit(2); } main(int argc, char *argv[]) { char *mmx; BASEPAGE *caller; char *prog; char *firstcmd; if(**argv) prog = *argv; else prog = "screen"; argc--; argv++; if(argc) { firstcmd = *argv; argc--; argv++; } else firstcmd = ""; if(argc) usage(prog); if(mmx = getenv("MMX")) { if(strncmp(mmx, "Master-Call", 11)) exit(1); mmx += 11; if(!(master = (BASEPAGE *) strtol(mmx, &mmx, 10)) || !(master_var = (char *) strtol(mmx, &mmx, 10)) || !(caller = (BASEPAGE *) strtol(mmx, &mmx, 10)) || (caller != _base->p_parent)) exit(1); install_module(1, firstcmd); } else if(!system(NULL)) install_module(1, firstcmd); install_module(0, firstcmd); system("-i"); remove_module(); }