This is mswin.c in view mode; [Download] [Up]
#include <config.h> #include <windows.h> #include <stdio.h> #include <slang.h> #include <process.h> #include <stdlib.h> #include <string.h> #include <dir.h> #include <time.h> #include <dos.h> #include <assert.h> #include <io.h> #include <errno.h> #include "display.h" #include "sysdep.h" #include "screen.h" #include "keymap.h" #include "hooks.h" #include "ins.h" #include "ledit.h" #include "misc.h" #include "cmds.h" #include "sig.h" #ifdef HAS_SUBPROCESSES # include "jprocess.h" #endif #ifndef _USERENTRY #define _USERENTRY #endif #define MSW_STRING_TYPE 1 #define MSW_INT_TYPE 2 #define MSW_COLOR_TYPE 3 #define MAX_KEYS 128 #define KEY_SHIFT 1 #define KEY_CONTROL 2 #define KEY_ALT 4 #define SPACE_CHAR (32 | (JNORMAL_COLOR << 8)) #define MOUSE_RELEASE 'U' #define MOUSE_DRAG 0 #define MOUSE_PRESS 'D' #define MAX_MENU_ID 256 /* externs */ extern char Jed_Root_Dir[256]; extern HINSTANCE _hInstance; extern HINSTANCE _hPrev; typedef struct { char *name; int type; char *dflt; void *buf; } Msw_Ini_Type; typedef struct { COLORREF bg; COLORREF fg; HBRUSH hbrBG; } Color_Type; typedef struct { char *name; int r, g, b; } Color_Value_Type; typedef struct { char title[30]; HWND w; HDC hdc; int ndc; char font_name[50]; int font_height; int font_bold; int font_width; HFONT font; int x; int y; int height; int width; int scroll_r1, scroll_r2; /* scrolling region */ int cursor_row, cursor_col; /* row column of cursor (1,1) origin */ int vis_curs_row, vis_curs_col; /* position of VISIBLE cursor */ int cursor_showing; Color_Type *current_color; int focus; } MSWindow_Type; LRESULT CALLBACK JEDWndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK EnumWndProc(HWND, LPARAM); void _USERENTRY msw_cleanup(void); static void msw_get_defaults(void); static void msw_get_default(Msw_Ini_Type *t); static void get_dc(void); static void release_dc(void); static void init_application(void); static void init_instance(void); static void process_message(void); static void show_cursor(void); static void hide_cursor(void); static void msw_normal_video(void); static void set_window_name(char *s); static void x_warp_pointer(void); static int x_insert_cutbuffer(void); static void x_region_2_cutbuffer(void); static int msw_system(char *, int *, int *); static int dos_system(char *); static void msw_define_color(char *, int *, int *, int *); static void get_menubar(void); static void destroy_menubar(void); static void create_popup_menu(void); static void destroy_menu(void); static void append_menu_item(void); static void append_popup_menu(void); static void append_separator(void); static void insert_menu_item(void); static void insert_menu_item_pos(void); static void insert_popup_menu(void); static void insert_popup_menu_pos(void); static void insert_separator(void); static void insert_separator_pos(void); static void delete_menu_item(void); static void delete_menu_item_pos(void); static void get_menu_state(void); static void get_menu_state_pos(void); static void get_popup_menu(void); static void check_menu_item(void); static void check_menu_item_pos(void); static void enable_menu_item(void); static void enable_menu_item_pos(void); static void redraw_menubar(void); static void set_init_popup_callback(void); static void msw_help(void); #ifdef __WIN32__ HINSTANCE _hPrev; # ifdef HAS_SUBPROCESSES HANDLE Input_Events[MAX_PROCESSES + 1]; # endif #endif int Abort_Char = 7; int NumLock_Is_Gold = 0; int PC_Alt_Char = 27; static HINSTANCE hPrevInst; static HINSTANCE hInstance; static char *szJedSection = "WJED"; static int JX_Screen_Cols; static int JX_Screen_Rows; static int JX_Term_Cannot_Scroll = 0; static int JX_Term_Cannot_Insert = 0; static int JX_Baud_Rate = 0; static int JX_Use_Ansi_Colors = 1; static int JX_Ignore_Beep = 3; static int Performing_Update; static MSWindow_Type This_Window; static Color_Type colors[JMAX_COLORS]; static char *InitPopup_Callback; static char *Menu_Callbacks[MAX_MENU_ID]; Msw_Ini_Type Msw_Ini_List[] = { { "Font", MSW_STRING_TYPE, "fixed", This_Window.font_name }, { "FontHeight", MSW_INT_TYPE, "12", &This_Window.font_height }, { "FontBold", MSW_INT_TYPE, "-1", &This_Window.font_bold }, { "Background", MSW_COLOR_TYPE, "0,0,0", &colors[JNORMAL_COLOR].bg }, { "Foreground", MSW_COLOR_TYPE, "192,192,192", &colors[JNORMAL_COLOR].fg }, { "StatusBG", MSW_COLOR_TYPE, "0,0,128", &colors[JSTATUS_COLOR].bg }, { "StatusFG", MSW_COLOR_TYPE, "255,255,0", &colors[JSTATUS_COLOR].fg }, { "RegionBG", MSW_COLOR_TYPE, "255,0,255", &colors[JREGION_COLOR].bg }, { "RegionFG", MSW_COLOR_TYPE, "255,255,255", &colors[JREGION_COLOR].fg }, { "OperatorBG", MSW_COLOR_TYPE, "0,0,0", &colors[JOP_COLOR].bg }, { "OperatorFG", MSW_COLOR_TYPE, "255,255,255", &colors[JOP_COLOR].fg }, { "NumberBG", MSW_COLOR_TYPE, "0,0,0", &colors[JNUM_COLOR].bg }, { "NumberFG", MSW_COLOR_TYPE, "0,0,192", &colors[JNUM_COLOR].fg }, { "StringBG", MSW_COLOR_TYPE, "0,0,0", &colors[JSTR_COLOR].bg }, { "StringFG", MSW_COLOR_TYPE, "0,192,255", &colors[JSTR_COLOR].fg }, { "CommentBG", MSW_COLOR_TYPE, "0,0,0", &colors[JCOM_COLOR].bg }, { "CommentFG", MSW_COLOR_TYPE, "0,128,0", &colors[JCOM_COLOR].fg }, { "KeywordBG", MSW_COLOR_TYPE, "0,0,0", &colors[JKEY_COLOR].bg }, { "KeywordFG", MSW_COLOR_TYPE, "255,255,255", &colors[JKEY_COLOR].fg }, { "Keyword1BG", MSW_COLOR_TYPE, "0,0,0", &colors[JKEY_COLOR + 1].bg }, { "Keyword1FG", MSW_COLOR_TYPE, "255,255,255", &colors[JKEY_COLOR + 1].fg }, { "DelimiterBG", MSW_COLOR_TYPE, "0,0,0", &colors[JDELIM_COLOR].bg }, { "DelimiterFG", MSW_COLOR_TYPE, "255,255,255", &colors[JDELIM_COLOR].fg }, { "PreprocessBG", MSW_COLOR_TYPE, "0,0,0", &colors[JPREPROC_COLOR].bg }, { "PreprocessFG", MSW_COLOR_TYPE, "0,255,0", &colors[JPREPROC_COLOR].fg }, { "MessageBG", MSW_COLOR_TYPE, "0,0,0", &colors[JMESSAGE_COLOR].bg}, { "MessageFG", MSW_COLOR_TYPE, "255,255,0", &colors[JMESSAGE_COLOR].fg}, { "ErrorFG", MSW_COLOR_TYPE, "255,0,0", &colors[JERROR_COLOR].fg}, { "ErrorBG", MSW_COLOR_TYPE, "0,0,0", &colors[JERROR_COLOR].bg}, { "MenuFG", MSW_COLOR_TYPE, "0,0,0", &colors[JMENU_COLOR].fg}, { "MenuBG", MSW_COLOR_TYPE, "0,255,255", &colors[JMENU_COLOR].bg}, {"CursorFG", MSW_COLOR_TYPE, "0,255,0", &colors[JCURSOR_COLOR].fg}, {"CursorBG", MSW_COLOR_TYPE, "255,0,0", &colors[JCURSOR_COLOR].bg}, {"DollarFG", MSW_COLOR_TYPE, "0,0,255", &colors[JDOLLAR_COLOR].fg}, {"DollarBG", MSW_COLOR_TYPE, "0,0,0", &colors[JDOLLAR_COLOR].bg}, { "Title", MSW_STRING_TYPE, "WJED", &This_Window.title }, { "X", MSW_INT_TYPE, "0", &This_Window.x }, { "Y", MSW_INT_TYPE, "0", &This_Window.y }, { "Width", MSW_INT_TYPE, "700", &This_Window.width }, { "Height", MSW_INT_TYPE, "500", &This_Window.height }, { NULL, 0, NULL, NULL } }; static Color_Value_Type Msw_Std_Color[] = { {"black", 0, 0, 0}, {"blue", 0, 0, 192}, {"green", 0, 128, 0}, {"cyan", 0, 192, 192}, {"red", 192, 0, 0}, {"magenta", 192, 0, 192}, {"lightgray", 192, 192, 192}, {"gray", 128, 128, 128}, {"brightblue", 0, 0, 255}, {"brightred", 255, 0, 0}, {"brightgreen", 0, 255, 0}, {"brightcyan", 0, 255, 255}, {"brightmagenta", 255, 0, 255}, {"yellow", 255, 255, 0}, {"white", 255, 255, 255}, {"brown", 110, 74, 32}, {NULL, 0, 0, 0} }; static SLang_Name_Type Sl_Msw_Table[] = { MAKE_INTRINSIC(".x_set_window_name", set_window_name, VOID_TYPE, 1), MAKE_INTRINSIC(".x_warp_pointer", x_warp_pointer, VOID_TYPE, 0), MAKE_INTRINSIC(".x_insert_cutbuffer", x_insert_cutbuffer, INT_TYPE, 0), /* Prototype: Integer x_insert_cut_buffer (); * Inserts cutbuffer into the current buffer and returns the number * of characters inserted. */ MAKE_INTRINSIC(".x_copy_region_to_cutbuffer", x_region_2_cutbuffer, VOID_TYPE, 0), /*Prototype: Void x_copy_region_to_cutbuffer();*/ MAKE_INTRINSIC(".define_color", msw_define_color, VOID_TYPE, 4), /*Prototype: Void msw_define_color(char *, int, int, int);*/ MAKE_INTRINSIC(".get_menubar", get_menubar, VOID_TYPE, 0), /* Prototype: Integer get_menubar(Void) * Returns integer which is handle of menubar. If there is no * menubar, it creates it. * To show menubar, call `redraw_menu' */ MAKE_INTRINSIC(".destroy_menubar", destroy_menubar, VOID_TYPE, 0), /* Prototype: Void destroy_menubar(Void) * Destroys menubar */ MAKE_INTRINSIC(".create_popup_menu", create_popup_menu, VOID_TYPE, 0), /* Prototype: Integer create_popup_menu(Void) * Creates empty popup menu and returns integer value which is * it's handle. If popup is not appended to another menu, it must * destroyed after use. */ MAKE_INTRINSIC(".destroy_menu", destroy_menu, VOID_TYPE, 0), /* Prototype: Void destroy_menu(Integer hmenu) * Destroys menu and all it's popup menus. * Note: Do not destroy menubar with this function * (use `destroy_menubar') */ MAKE_INTRINSIC(".append_menu_item", append_menu_item, VOID_TYPE, 0), /* Prototype: Void append_menu_item(Integer hmenu, String name, Integer id, String callback) * Appends menu item with name 'name' and identifier 'id' at the end * of 'hmenu'. When item is selected, the 'callback' will be executed. * Callback can be intrinsic or internal function. */ MAKE_INTRINSIC(".append_popup_menu", append_popup_menu, VOID_TYPE, 0), /* Prototype: Void append_popop_menu(Integer hmenu, String name, Integer popup) * Appends popup menu with name 'name' and handle 'popup' at the end * of 'hmenu' */ MAKE_INTRINSIC(".append_separator", append_separator, VOID_TYPE, 0), /* Prototype: Void append_separator(Integer hmenu) * Appends menu separator at the end of 'hmenu' */ MAKE_INTRINSIC(".insert_menu_item", insert_menu_item, VOID_TYPE, 0), /* Prototype: Void insert_menu_item(Integer hmenu, Integer id, String name, Integer idNew, String callback) * Inserts menu item with name 'name' and identifier 'idNew' before * menu item with identifier 'id'. * When item is selected, the 'callback' will be executed. * Callback can be intrinsic or internal function. */ MAKE_INTRINSIC(".insert_menu_item_pos", insert_menu_item_pos, VOID_TYPE, 0), /* Prototype: Void insert_menu_item_pos(Integer hmenu, Integer pos, String name, Integer idNew, String callback) * Inserts menu item with name 'name' and identifier 'idNew' before * menu item with zero-based position 'pos' in 'hmenu'. * When item is selected, the 'callback' will be executed. * Callback can be intrinsic or internal function. */ MAKE_INTRINSIC(".insert_popup_menu", insert_popup_menu, VOID_TYPE, 0), /* Prototype: Void insert_popup_menu(Integer hmenu, Integer id, String name, Integer popup) * Inserts popup menu with name 'name' and handle 'popup' before * menu item with identifier 'id' */ MAKE_INTRINSIC(".insert_popup_menu_pos", insert_popup_menu_pos, VOID_TYPE, 0), /* Prototype: Void insert_popup_menu_pos(Integer hmenu, Integer pos, String name, Integer popup) * Inserts popup menu with name 'name' and handle 'popup' before * menu item with zero-based position 'pos' in 'hmenu' */ MAKE_INTRINSIC(".insert_separator", insert_separator, VOID_TYPE, 0), /* Prototype: Void insert_separator(Integer hmenu, Integer id) * Inserts menu separator before menu item with identifier 'id' */ MAKE_INTRINSIC(".insert_separator_pos", insert_separator_pos, VOID_TYPE, 0), /* Prototype: Void insert_separator_pos(Integer hmenu, Integer pos) * Inserts menu separator before menu item with zero-based position 'pos' */ MAKE_INTRINSIC(".delete_menu_item", delete_menu_item, VOID_TYPE, 0), /* Prototype: Void delete_menu_item(Integer hmenu, Integer id) * Deletes menu item with identifier id from menu with handle 'hmenu' */ MAKE_INTRINSIC(".delete_menu_item_pos", delete_menu_item_pos, VOID_TYPE, 0), /* Prototype: Void delete_menu_item_pos(Integer hmenu, Integer pos) * Deletes menu item at zero-based position 'pos' from menu 'hmenu' */ MAKE_INTRINSIC(".get_menu_state", get_menu_state, VOID_TYPE, 0), /* Prototype: Integer get_menu_state(Integer hmenu, Integer id) * Gets state of menu item with identifier 'id' * <return value> & 1 == 1 if menu item is enabled * <return value> & 2 == 1 if menu item is checked */ MAKE_INTRINSIC(".get_menu_state_pos", get_menu_state_pos, VOID_TYPE, 0), /* Prototype: Integer get_menu_state(Integer hmenu, Integer pos) * Gets state of menu item at zero-based position 'pos' * <return value> & 1 == 1 if menu item is enabled * <return value> & 2 == 1 if menu item is checked */ MAKE_INTRINSIC(".get_popup_menu", get_popup_menu, VOID_TYPE, 0), /* Prototype: Void get_popup_menu(Integer hmenu, Integer pos) * Returns handle of popup menu at zero-based position 'pos' * If return value is 0, there is no popup at the position. */ MAKE_INTRINSIC(".check_menu_item", check_menu_item, VOID_TYPE, 0), /* Prototype: Void check_menu_item(Integer hmenu, Integer id, Integer flag) * This functions changes check state of menu item. If flag is nonzero, * it checks menu item, otherwise it unchecks it */ MAKE_INTRINSIC(".check_menu_item_pos", check_menu_item_pos, VOID_TYPE, 0), /* Prototype: Void check_menu_item(Integer hmenu, Integer pos, Integer flag) * This functions changes check state of menu item. If flag is nonzero, * it checks menu item, otherwise it unchecks it */ MAKE_INTRINSIC(".enable_menu_item", enable_menu_item, VOID_TYPE, 0), /* Prototype: Void check_menu_item(Integer hmenu, Integer id, Integer flag) * This functions enable or disable menu item. If flag is nonzero, the * menu item will be enabled, otherwise it'll be disabled. */ MAKE_INTRINSIC(".enable_menu_item_pos", enable_menu_item_pos, VOID_TYPE, 0), /* Prototype: Void check_menu_item(Integer hmenu, Integer pos, Integer flag) * This functions enable or disable menu item. If flag is nonzero, the * menu item will be enabled, otherwise it'll be disabled. */ MAKE_INTRINSIC(".redraw_menubar", redraw_menubar, VOID_TYPE, 0), /* Prototype: Void redraw_menubar(Void) * Redraws menubar. This functions should be called if menubar is changed */ MAKE_INTRINSIC(".set_init_popup_callback", set_init_popup_callback, VOID_TYPE, 0), /* Prototype: Void set_init_popup_callback(String callback) * Executes callback before menu poppup was popped up. */ MAKE_INTRINSIC(".msw_help", msw_help, VOID_TYPE, 0), /* Prototype: Void msw_help(String filename, String keword, Integer Partial_Keys) * Starts Windows Help with 'filename' help file. If 'keyword' is not null * string shows topic with specified keyword. If 'Partial_Keys' != 0 * shows Search dialog if there is more than one help topic beginnig with * 'keyword' */ SLANG_END_TABLE }; /* Key storage functions */ static void _putkey(char c) { int ch = c; ungetkey(&ch); } /* Getting defaults from INI file */ static COLORREF msw_get_color(char *s, char *dflt) { if (s[0] >= '0' && s[0] <= '9') { long r, g, b; char *sptr, *endptr; sptr = s; r = strtol(sptr, &endptr, 0); while ((*endptr == ' ') || (*endptr == '\t')) endptr++; /* skipping whitespace */ if ((sptr == endptr) || (*endptr++ != ',')) return msw_get_color(dflt, dflt); sptr = endptr; g = strtol(sptr, &endptr, 0); while ((*endptr == ' ') || (*endptr == '\t')) endptr++; /* skipping whitespace */ if ((sptr == endptr) || (*endptr++ != ',')) return msw_get_color(dflt, dflt); sptr = endptr; b = strtol(sptr, &endptr, 0); while ((*endptr == ' ') || (*endptr == '\t')) endptr++; /* skipping whitespace */ if ((sptr == endptr) || (*endptr++ != 0)) return msw_get_color(dflt, dflt); return RGB((BYTE)r, (BYTE)g, (BYTE)b); } else { char buf[50]; GetProfileString(szJedSection, s, dflt, buf, sizeof(buf)); if (buf[0] >='0' && buf[0] <= '9') return msw_get_color(buf, dflt); else return msw_get_color(dflt, dflt); } } static void msw_get_default(Msw_Ini_Type *t) { char s[50]; GetProfileString(szJedSection, t->name, t->dflt, s, sizeof(s)); switch (t->type) { case MSW_STRING_TYPE: strcpy((char *)t->buf, s); break; case MSW_INT_TYPE: *(int *)t->buf = atoi(s); break; case MSW_COLOR_TYPE: *(COLORREF *)t->buf = msw_get_color(s, t->dflt); break; } } static void msw_get_defaults(void) { int i = 0; char buf[20]; /* Check for standard color names in INI file. * Add they if cannot find. */ while (Msw_Std_Color[i].name != NULL) { if (!GetProfileString(szJedSection, Msw_Std_Color[i].name, "", buf, sizeof(buf))) msw_define_color(Msw_Std_Color[i].name, &Msw_Std_Color[i].r, &Msw_Std_Color[i].g, &Msw_Std_Color[i].b); i++; } i = 0; while (Msw_Ini_List[i].name != NULL) msw_get_default(&Msw_Ini_List[i++]); } static void get_dc(void) { if (!This_Window.ndc) This_Window.hdc = GetDC(This_Window.w); This_Window.ndc++; } static void release_dc(void) { assert(This_Window.ndc); if (This_Window.ndc == 1) ReleaseDC(This_Window.w, This_Window.hdc); This_Window.ndc--; } static void process_message(void) { MSG msg; if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } } static void init_application(void) { WNDCLASS wc; wc.style = 0; wc.lpfnWndProc = JEDWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_IBEAM); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "wjed"; RegisterClass(&wc); } static void init_instance(void) { int i; TEXTMETRIC tm; int font_weight; This_Window.hdc = NULL; This_Window.ndc = 0; for (i = 0; i < MAX_MENU_ID; i++) Menu_Callbacks[i] = NULL; InitPopup_Callback = NULL; msw_get_defaults(); /* creating fonts, brushes etc */ if (This_Window.font_bold < 0) font_weight = FW_DONTCARE; else font_weight = (This_Window.font_bold > 0) ? FW_BOLD : FW_NORMAL; This_Window.font = CreateFont(-This_Window.font_height, 0, 0, 0, font_weight, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, FIXED_PITCH, This_Window.font_name); for (i = 0; i < JMAX_COLORS; i++) colors[i].hbrBG = CreateSolidBrush(colors[i].bg); msw_normal_video(); /* creating window */ This_Window.w = CreateWindow("wjed", This_Window.title, WS_OVERLAPPEDWINDOW, This_Window.x, This_Window.y, This_Window.width,This_Window.height, NULL, NULL, hInstance, NULL); /* function that will be called when jed exits (deletes fonts, brushes etc.) */ atexit(msw_cleanup); /* retrieve font metrics (width and base) */ get_dc(); SelectObject(This_Window.hdc, This_Window.font); GetTextMetrics(This_Window.hdc, &tm); This_Window.font_width = tm.tmAveCharWidth; This_Window.font_height = tm.tmHeight; release_dc(); ShowWindow(This_Window.w, SW_SHOW); UpdateWindow(This_Window.w); #if !defined(__WIN32__) || !defined(HAS_SUBPROCESS) SetTimer(This_Window.w, 42, 30000, NULL); /* used for updating display time */ #endif } void init_tty (void) { if (Batch) return; hInstance = _hInstance; hPrevInst = _hPrev; if (!hPrevInst) init_application(); init_instance(); } void reset_tty(void) { } static void copy_rect(int x1, int y1, int x2, int y2, int x3, int y3) { int dx, dy; RECT rcSrc; dx = (x3 - x1) * This_Window.font_width; dy = (y3 - y1) * This_Window.font_height; SetRect(&rcSrc, x1 * This_Window.font_width, y1 * This_Window.font_height, x2 * This_Window.font_width, y2 * This_Window.font_height); ScrollWindow(This_Window.w, dx, dy, &rcSrc, NULL); #ifdef __WIN32__ UpdateWindow(This_Window.w); #endif } static void blank_rect(int x1, int y1, int x2, int y2) { RECT rc; SetRect(&rc, x1 * This_Window.font_width, y1 * This_Window.font_height, x2 * This_Window.font_width, y2 * This_Window.font_height); get_dc(); FillRect(This_Window.hdc, &rc, colors[JNORMAL_COLOR].hbrBG); release_dc(); } /* This routine assumes that cursor is in the correct location. The cursor is placed at the end of the string. */ static void tt_write(char *s, int n) { get_dc(); if (This_Window.cursor_showing) hide_cursor(); SelectObject(This_Window.hdc, This_Window.font); SetTextColor(This_Window.hdc, This_Window.current_color->fg); SetBkColor(This_Window.hdc, This_Window.current_color->bg); TextOut(This_Window.hdc, This_Window.cursor_col * This_Window.font_width, This_Window.cursor_row * This_Window.font_height, s, n); This_Window.cursor_col += n; if (This_Window.cursor_col >= JX_Screen_Cols) This_Window.cursor_col = JX_Screen_Cols - 1; release_dc(); } static void hide_cursor(void) { unsigned short *s; char ch; int col = This_Window.vis_curs_col, row = This_Window.vis_curs_row; Color_Type *color; if (This_Window.cursor_showing == 0) return; This_Window.cursor_showing = 0; s = JScreen[row].old; if (s == NULL) return; s += col; ch = (char) (*s & 0xFF); get_dc(); color = &colors[*s >> 8]; SelectObject(This_Window.hdc, This_Window.font); SetTextColor(This_Window.hdc, color->fg); SetBkColor(This_Window.hdc, color->bg); TextOut(This_Window.hdc, This_Window.cursor_col * This_Window.font_width, This_Window.cursor_row * This_Window.font_height, &ch, 1); release_dc(); } static void show_cursor(void) { unsigned short *s; char ch; int c, r; Color_Type *curs_color; RECT rc; if (This_Window.cursor_showing) hide_cursor(); This_Window.cursor_showing = 1; r = This_Window.vis_curs_row = This_Window.cursor_row; c = This_Window.vis_curs_col = This_Window.cursor_col; s = JScreen[r].old; if (s == NULL) return; s += c; ch = (char) (*s & 0xFF); curs_color = &colors[JCURSOR_COLOR]; get_dc(); if (This_Window.focus) { SelectObject(This_Window.hdc, This_Window.font); SetTextColor(This_Window.hdc, curs_color->fg); SetBkColor(This_Window.hdc, curs_color->bg); TextOut(This_Window.hdc, This_Window.cursor_col * This_Window.font_width, This_Window.cursor_row * This_Window.font_height, &ch, 1); } else { rc.left = This_Window.cursor_col * This_Window.font_width; rc.top = This_Window.cursor_row * This_Window.font_height; rc.right = rc.left + This_Window.font_width; rc.bottom = rc.top + This_Window.font_height; FrameRect(This_Window.hdc, &rc, curs_color->hbrBG); } release_dc(); } #if !defined(__WIN32__) || !defined(HAS_SUBPROCESSES) unsigned char sys_getkey(void) { int n; while (!SLKeyBoard_Quit && !Input_Buffer_Len) process_message (); if (SLKeyBoard_Quit) return Abort_Char; n = my_getkey(); SLKeyBoard_Quit = 0; return n; } int sys_input_pending(int *tsecs, int unused) { DWORD t = GetTickCount() + *tsecs * 100L; (void) unused; while ((!Input_Buffer_Len) && (GetTickCount() < t)) process_message(); return Input_Buffer_Len != 0; } #else unsigned char sys_getkey(void) { int n = 450; if (SLKeyBoard_Quit) return((unsigned char)Abort_Char); /* sleep for 45 second and try again */ while (!SLKeyBoard_Quit && !sys_input_pending(&n, Num_Subprocesses)) { /* update status line incase user is displaying time */ if (SLKeyBoard_Quit) break; JWindow->trashed = 1; update((Line *) NULL, 0, 1); } if (SLKeyBoard_Quit) return (unsigned char)Abort_Char; n = my_getkey(); SLKeyBoard_Quit = 0; return (unsigned char) n; } int sys_input_pending(int *tsecs, int all) { DWORD ret; int i, n; if ((all >= 0) && (Input_Buffer_Len || Batch)) return (Input_Buffer_Len); if (all < 0) { ret = WaitForMultipleObjects(Num_Subprocesses, Input_Events, FALSE, *tsecs * 100); } else { DWORD t; long rtime = *tsecs * 100L; do { t = GetTickCount(); ret = MsgWaitForMultipleObjects(Num_Subprocesses, Input_Events, FALSE, rtime, QS_ALLINPUT); if ((WAIT_OBJECT_0 + Num_Subprocesses) != ret) break; rtime -= GetTickCount() - t; process_message(); } while ((rtime > 0) && !Input_Buffer_Len); if ((rtime < 0) || Input_Buffer_Len) return Input_Buffer_Len; } if (WAIT_TIMEOUT == ret) return 0; i = n = 0; while (i < Num_Subprocesses) { /* Check if current subprocess has input */ if (WAIT_TIMEOUT != WaitForSingleObject(Input_Events[i], 0)) { read_process_input (i); n++; } i++; } if (all < 0) return n; else return 0; } #endif void sys_suspend(void) { ShowWindow(This_Window.w, SW_MINIMIZE); } int get_term_dimensions(int *cols, int *rows) { *cols = This_Window.width / This_Window.font_width; *rows = This_Window.height / This_Window.font_height; return 0; } /* Hooks */ static void msw_update_open (void) { hide_cursor (); Performing_Update = 1; } static void msw_update_close (void) { Performing_Update = 0; if (JWindow->trashed) return; show_cursor (); } static void msw_suspend (void) { WINDOWPLACEMENT wndpl; GetWindowPlacement(This_Window.w, &wndpl); if (wndpl.showCmd == SW_MINIMIZE) ShowWindow(This_Window.w, SW_NORMAL); else ShowWindow(This_Window.w, SW_MINIMIZE); } static int msw_init_slang (void) { SLadd_name ("msw_system", (long) msw_system, SLANG_INTRINSIC, SLANG_MAKE_ARGS(INT_TYPE, 3)); return SLang_add_table(Sl_Msw_Table, "MSWJed") && SLdefine_for_ifdef("MSWINDOWS") && SLdefine_for_ifdef("MOUSE"); } static void msw_define_xkeys (SLKeyMap_List_Type *map) { SLkm_define_key ("^[Ow", (FVOID_STAR) bob, map); SLkm_define_key ("^[Oq", (FVOID_STAR) eob, map); SLkm_define_key ("\xE0\xE0", (FVOID_STAR) ins_char_cmd, map); } /* This routine is called from S-Lang inner interpreter. It serves as a poor mans version of an interrupt 9 handler */ static void msw_check_kbd(void) { MSG msg; if (Batch) return; while (PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) process_message(); } /* Terminal functions */ static void msw_goto_rc(int r, int c) { get_dc(); if (This_Window.cursor_showing) hide_cursor(); if (r > JX_Screen_Rows) r = JX_Screen_Rows; if (c > JX_Screen_Cols) c = JX_Screen_Cols; This_Window.cursor_row = r + This_Window.scroll_r1; This_Window.cursor_col = c; if (!Performing_Update) show_cursor(); release_dc(); } static void msw_begin_insert(void) { hide_cursor(); copy_rect(This_Window.cursor_col, This_Window.cursor_row, JX_Screen_Cols - 1, This_Window.cursor_row + 1, This_Window.cursor_col + 1, This_Window.cursor_row); } static void msw_end_insert(void) { } static void msw_del_eol(void) { blank_rect(This_Window.cursor_col, This_Window.cursor_row, JX_Screen_Cols, This_Window.cursor_row + 1); } static void msw_delete_nlines(int n) { int r1, r2; r1 = This_Window.cursor_row; r2 = This_Window.scroll_r2; if (r1 <= r2 - n) copy_rect(0, r1 + n, JX_Screen_Cols, r2 + 1, 0, r1); if (Scroll_By_Copying == 0) blank_rect(0, r2 - n, JX_Screen_Cols, r2); } static void msw_delete_char(void) { copy_rect(This_Window.cursor_col + 1, This_Window.cursor_row, JX_Screen_Cols, This_Window.cursor_row + 1, This_Window.cursor_col, This_Window.cursor_row); } static void msw_erase_line(void) { blank_rect(0, This_Window.cursor_row, JX_Screen_Cols, This_Window.cursor_row + 1); } static int Rev_Vid_Flag; static void msw_reverse_video(int color) { Rev_Vid_Flag = color; This_Window.current_color = &colors[color]; } static void msw_normal_video(void) { Rev_Vid_Flag = JNORMAL_COLOR; This_Window.current_color = &colors[JNORMAL_COLOR]; } static void msw_cls(void) { RECT rc; get_dc(); GetClientRect(This_Window.w, &rc); FillRect(This_Window.hdc, &rc, colors[JNORMAL_COLOR].hbrBG); release_dc(); } static void msw_beep(void) { if (JX_Ignore_Beep & 0x1) MessageBeep(0); if (JX_Ignore_Beep & 0x2) { RECT rc; get_dc(); GetClientRect(This_Window.w, &rc); InvertRect(This_Window.hdc, &rc); release_dc(); InvalidateRect(This_Window.w, NULL, TRUE); } MessageBeep(0); } static void msw_reverse_index(int n) { int r1, r2; r1 = This_Window.scroll_r1; r2 = This_Window.scroll_r2; if (r2 >= r1 + n) copy_rect(0, r1, JX_Screen_Cols, r2 - n + 1, 0, r1 + n); if (Scroll_By_Copying == 0) blank_rect(0, r1, JX_Screen_Cols, r1 + n); } static void msw_write_string (char *s) { get_dc(); tt_write(s, strlen(s)); if (!Performing_Update) show_cursor (); release_dc(); } static void send_attr_str(unsigned short *s, unsigned short *smax) { unsigned char out[250], ch, attr, *p; register unsigned short sh; p = out; get_dc(); while (s < smax) { sh = (unsigned short) *s++; ch = sh & 0xFF; attr = sh >> 8; if ((attr == 0) && (Rev_Vid_Flag != 0)) { if (p != out) { *p = 0; msw_write_string ((char *) out); p = out; } tt_normal_video(); /* Rev_Vid_Flag = 0; */ } else if ((attr != 0) && (Rev_Vid_Flag != attr)) { if (p != out) { *p = 0; msw_write_string ((char *) out); p = out; } msw_reverse_video(attr); /* Rev_Vid_Flag = 1; */ } *p++ = ch; } *p = 0; if (p != out) msw_write_string ((char *) out); /* if (Rev_Vid_Flag) tt_normal_video(); */ release_dc(); } static void msw_smart_puts(unsigned short *neww, unsigned short *oldd, int len, int row) { if (0 == memcmp ((char *) neww, (char *) oldd, len * sizeof (short))) return; msw_goto_rc (row, 0); send_attr_str (neww, neww + len); } /* This function is called assuming that cursor is in correct position */ static void msw_putchar(char ch) { if (ch == '\b') { ch = ' '; if (This_Window.cursor_col == 0) return; This_Window.cursor_col--; } get_dc(); if (Rev_Vid_Flag != JNORMAL_COLOR) tt_normal_video(); tt_write(&ch, 1); show_cursor (); release_dc(); } static void msw_init_video (void) { } static void msw_reset_video (void) { tt_normal_video (); } static void msw_set_scroll_region(int r1, int r2) { This_Window.scroll_r1 = r1; This_Window.scroll_r2 = r2; } static void msw_reset_scroll_region() { This_Window.scroll_r1 = 0; This_Window.scroll_r2 = JX_Screen_Cols - 1; } static void msw_get_terminfo() { JX_Screen_Cols = 80; JX_Screen_Rows = 24; Scroll_By_Copying = 1; /* init hooks */ X_Update_Open_Hook = msw_update_open; X_Update_Close_Hook = msw_update_close; X_Suspend_Hook = msw_suspend; /* X_Argc_Argv_Hook = X_eval_command_line; */ X_Init_SLang_Hook = msw_init_slang; X_Define_Keys_Hook = msw_define_xkeys; SLang_Interrupt = msw_check_kbd; /* Set this so that main will not try to read from stdin. It is quite * likely that this is started from a menu or something. */ Stdin_Is_TTY = -1; } static void msw_set_color (int i, char *what, char *fg, char *bg) { int r, g, b; char buf[30]; (void) what; r = GetRValue(colors[i].fg); g = GetGValue(colors[i].fg); b = GetBValue(colors[i].fg); sprintf(buf, "%d,%d,%d", r, g, b); colors[i].fg = msw_get_color(fg, buf); r = GetRValue(colors[i].bg); g = GetGValue(colors[i].bg); b = GetBValue(colors[i].bg); sprintf(buf, "%d,%d,%d", r, g, b); colors[i].bg = msw_get_color(bg, buf); DeleteObject(colors[i].hbrBG); colors[i].hbrBG = CreateSolidBrush(colors[i].bg); /* InvalidateRect(This_Window.w, NULL, FALSE); */ } static void msw_narrow_width (void) { } static void msw_wide_width (void) { } static void msw_enable_cursor_keys(void) { } static void msw_set_term_vtxxx (int *n) { (void) n; } typedef struct _Process_Info { HINSTANCE hInstance; HWND hWnd; HTASK hTask; } Process_Info; int msw_system(char *command_line, int *nCmdShow, int *wait) { UINT retcode; Process_Info pi; WNDENUMPROC enumproc; HCURSOR hcur, hcur_old; MSG msg; retcode = WinExec(command_line, *nCmdShow); if (retcode < 32) { switch (retcode) { case 0: case 11: case 12: case 14: case 15: msg_error("Invalid EXE file"); break; case 2: msg_error("File not found"); break; case 3: msg_error("Path not found"); break; case 8: msg_error("Out of memory"); break; case 10: msg_error("Incorrect MS Windows version"); break; case 16: msg_error("Cannot run more that one instance of application"); break; case 20: msg_error("Cannot find one of required DLL's"); break; case 21: msg_error("Application requires MS Windows 32-bit extension"); break; default: msg_error("Unknown error"); } return retcode; } if (!*wait) return 0; pi.hInstance = (HINSTANCE) retcode; pi.hWnd = NULL; pi.hTask = NULL; enumproc = (WNDENUMPROC) MakeProcInstance((FARPROC)EnumWndProc,hInstance); EnumWindows(enumproc, (LPARAM) &pi); FreeProcInstance((FARPROC)enumproc); hcur = LoadCursor(NULL, IDC_WAIT); hcur_old = SetCursor(hcur); while (1) { #ifdef __WIN32__ if (!IsWindow(pi.hWnd)) break; if ((HINSTANCE) GetWindowLong(pi.hWnd, GWL_HINSTANCE) != pi.hInstance) break; #else if (!IsWindow(pi.hWnd) || !IsTask(pi.hTask)) break; if ((HINSTANCE) GetWindowWord(pi.hWnd, GWW_HINSTANCE) != pi.hInstance) break; if (GetWindowTask(pi.hWnd) != pi.hTask) break; #endif if (PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) { process_message(); SetCursor(hcur); } } SetCursor(hcur_old); return 0; } BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam) { Process_Info *pi = (Process_Info *) lParam; if ((HINSTANCE) #ifdef __WIN32__ GetWindowLong(hWnd, GWL_HINSTANCE) #else GetWindowWord(hWnd, GWW_HINSTANCE) #endif == pi->hInstance) { pi->hWnd = hWnd; pi->hTask = GetWindowTask(hWnd); return FALSE; } return TRUE; } int sys_System(char *command_line) { return dos_system(command_line); } static int dos_system(char *command_line) { char *tmp_file = "jedshell.tmp"; char buf[256]; FILE *f; int ret; int nCmdShow = SW_SHOWMINIMIZED; int wait = TRUE; sprintf(buf, "%s\\bin\\mswshell.pif %s", Jed_Root_Dir, command_line); sys_delete_file(tmp_file); if (msw_system(buf, &nCmdShow, &wait) != 0) return 1; if (NULL == (f = fopen(tmp_file, "r"))) return 1; fgets(buf, sizeof(buf), f); ret = (int) atol(buf); *buf = 0; fgets(buf, sizeof(buf), f); fclose(f); sys_delete_file(tmp_file); if (*buf != 0) msg_error(buf); return ret; } /* to make slang.lib happy * There is no definition of function system for MS Windows */ int system(const char *command) { return sys_System((char *) command); } static void cover_exposed_area (int x, int y, int width, int height) { unsigned short *s, *smax; int row, save_row, save_col, max_col, max_row, col; Performing_Update++; hide_cursor (); save_row = This_Window.cursor_row; save_col = This_Window.cursor_col; col = x / This_Window.font_width; row = y / This_Window.font_height; max_col = 2 + col + width / This_Window.font_width; max_row = 2 + row + height / This_Window.font_height; if (max_col > JX_Screen_Cols) max_col = JX_Screen_Cols; if (max_row > JX_Screen_Rows) max_row = JX_Screen_Rows; for (This_Window.cursor_row = row; This_Window.cursor_row < max_row; This_Window.cursor_row++) { This_Window.cursor_col = col; s = JScreen[This_Window.cursor_row].old + This_Window.cursor_col; smax = JScreen[This_Window.cursor_row].old + max_col; if (s) send_attr_str(s, smax); } This_Window.cursor_row = save_row; This_Window.cursor_col = save_col; Performing_Update--; show_cursor (); } static void push_mouse_event(char button, int x, int y, int state, char type) { unsigned int s = 0; int col, row; static char last_button; if (button == 0) button = last_button; else last_button = button; if (state & MK_LBUTTON) s |= 1; if (state & MK_MBUTTON) s |= 2; if (state & MK_RBUTTON) s |= 4; switch (button) { case 'l': if (!(GetKeyState(VK_MENU) & 0x8000)) { JMouse.button = 1; break; } button = 'm'; /* drop */ case 'm': JMouse.button = 2; break; case 'r': JMouse.button = 3; break; default: JMouse.button = 0; } if (state & MK_CONTROL) { button = button - 'a' + 1; s |= 8; } if (state & MK_SHIFT) { button = button - 'a' + 'A'; s |= 16; } col = 1 + x / This_Window.font_width; row = 1 + y / This_Window.font_height; if ((col == JMouse.x) && (row == JMouse.y) && (type == 0)) return; if ((type == MOUSE_RELEASE) && (!JMouse.state & (1 << (JMouse.button - 1)))) return; JMouse.state = s; JMouse.x = col; JMouse.y = row; _putkey(button); _putkey(type); _putkey(0); _putkey('\033'); } static void x_warp_pointer (void) { } static void x_region_2_cutbuffer (void) { int nbytes; char *dat; int i, x; HGLOBAL hBuf; char *buf; dat = make_buffer_substring(&nbytes); if (dat == NULL) return; OpenClipboard(This_Window.w); EmptyClipboard(); for(i = x = 0; i < nbytes; i++) if (dat[i] == '\n') x++; hBuf = GlobalAlloc(GHND, x + nbytes); buf = (char *) GlobalLock(hBuf); for(i = x = 0; i < nbytes; i++) { if (dat[i] == '\n') buf[x++] = '\r'; buf[x++] = dat[i]; } GlobalUnlock(hBuf); SetClipboardData(CF_TEXT, hBuf); CloseClipboard(); } static int x_insert_cutbuffer (void) { int nbytes = 0; char *dat; int i, x; HGLOBAL hBuf; char *buf; CHECK_READ_ONLY OpenClipboard(This_Window.w); hBuf = GetClipboardData(CF_TEXT); CloseClipboard(); if (hBuf) { buf = (char *)GlobalLock(hBuf); for(i = x = 0; buf[i] != 0; i++) if (buf[i] != '\r') x++; nbytes = x; dat = SLMALLOC(x + 1); for(i = x = 0; buf[i] != 0; i++) if (buf[i] != '\r') dat[x++] = buf[i]; dat[x] = 0; ins_chars((unsigned char *) dat, nbytes); GlobalUnlock(hBuf); } return nbytes; } static void msw_define_color(char *color_name, int *pr, int *pg, int *pb) { char buf[30]; sprintf(buf, "%d,%d,%d", *pr, *pg, *pb); WriteProfileString(szJedSection, color_name, buf); } static void set_window_name (char *s) { if (Batch) return; strcpy(This_Window.title, s); SetWindowText(This_Window.w, s); } static void _USERENTRY msw_cleanup(void) { int i; char buf[10]; RECT rc; GetWindowRect(This_Window.w, &rc); itoa(rc.left, buf, 10); WriteProfileString(szJedSection, "X", buf); itoa(rc.top, buf, 10); WriteProfileString(szJedSection, "Y", buf); itoa(rc.right - rc.left, buf, 10); WriteProfileString(szJedSection, "Width", buf); itoa(rc.bottom - rc.top, buf, 10); WriteProfileString(szJedSection, "Height", buf); KillTimer(This_Window.w, 42); if (This_Window.w) DestroyWindow(This_Window.w); DeleteObject(This_Window.font); for(i = 0; i < JMAX_COLORS; i++) if (colors[i].hbrBG) DeleteObject(colors[i].hbrBG); } static int Ignore_Wchar_Message; static char f_keys[4][12] = { { 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 133, 134 }, { 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 135, 136 }, { 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 137, 138 }, { 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 139, 140 } }; static char small_keypad_keys[4][13] = { { 'G', 'H', 'I', 0, 'K', 0, 'M', 0, 'O', 'P', 'Q', 'R', 'S' }, { '0', '1', '2', 0, '3', 0, '4', 0, '5', '6', '7', '8', '9' }, { 'w', 141, 132, 0, 's', 0, 't', 0, 'u', 145, 'v', 146, 147 }, { 151, 152, 153, 0, 155, 0, 157, 0, 159, 160, 161, 162, 163 } }; static char num_keypad_keys[4][13] = { { 'w', 'x', 'y', 0, 't', 'u', 'v', 0, 'q', 'r', 's', 'p', 'n' }, { '0', '1', '2', 0, '3', 0 , '4', 0, '5', '6', '7', '8', '9' }, { 'w', 141, 132, 0, 's', 143, 't', 0, 'u', 145, 'v', 146, 147 }, { 'w', 'x', 'y', 0, 't', 'u', 'v', 0, 'q', 'r', 's', 'p', 'n' } }; LRESULT CALLBACK process_key_down (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { unsigned int key_state = 0; unsigned int scan; char prefix, c1; int i, state; if (GetKeyState(VK_CONTROL) & 0x8000) key_state |= KEY_CONTROL; if (GetKeyState(VK_SHIFT) & 0x8000) key_state |= KEY_SHIFT; if (GetKeyState(VK_MENU) & 0x8000) key_state |= KEY_ALT; Ignore_Wchar_Message = 0; scan = (unsigned int) ((lParam >> 16) & 0x1FF); switch (scan) { default: return DefWindowProc(hWnd, msg, wParam, lParam); case 0x00E: /* backspace */ _putkey (127); Ignore_Wchar_Message = 1; return 0; case 0x039: /* space */ if (key_state & KEY_CONTROL) { Ignore_Wchar_Message = 1; _putkey (3); _putkey (0); } return 0; case 0x003: /* 2 key */ if (key_state & KEY_CONTROL) { Ignore_Wchar_Message = 1; _putkey (0); return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); case 0x00C: /* -/_ key */ if (key_state & KEY_CONTROL) { Ignore_Wchar_Message = 1; _putkey (31); /* ^_ */ return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); case 0xE02F: c1 = 'Q'; break; /* KEYPAD SLASH */ case 0x037: /* KEYPAD STAR */ c1 = 'R'; break; case 0x04A: /* KEYPAD MINUS */ c1 = 'S'; break; case 0x04E: /* KEYPAD PLUS */ c1 = 'm'; break; case 0x047: /* KEYPAD HOME */ case 0x048: /* KEYPAD UP */ case 0x049: /* KEYPAD PGUP */ case 0x04B: /* KEYPAD LEFT */ case 0x04C: /* KEYPAD 5 */ case 0x04D: /* KEYPAD RIGHT */ case 0x04F: /* KEYPAD END */ case 0x050: /* KEYPAD DOWN */ case 0x051: /* KEYPAD PGDN */ case 0x053: /* KEYPAD DEL */ case 0x052: /* KEYPAD INSERT */ if (GetKeyState(VK_NUMLOCK) & 0x0001) return DefWindowProc(hWnd, msg, wParam, lParam); state = 0; if (key_state & KEY_SHIFT) state = 1; if (key_state & KEY_CONTROL) state = 2; if (key_state & KEY_ALT) state = 3; if (key_state & (KEY_CONTROL | KEY_ALT)) { Ignore_Wchar_Message = 1; _putkey (num_keypad_keys[state][scan - 0x47]); _putkey (0); return 0; } else c1 = num_keypad_keys[state][scan - 0x47]; break; case 0x11C: /* KEYPAD ENTER */ if (key_state & KEY_ALT) { _putkey(166); _putkey(0); Ignore_Wchar_Message = 1; return 0; } else { c1 = 'M'; break; } case 0x147: /* home */ case 0x148: /* UP */ case 0x149: /* PGUP */ case 0x14B: /* LEFT */ case 0x14D: /* RIGHT */ case 0x14F: /* END */ case 0x150: /* DOWN */ case 0x151: /* PGDN */ case 0x153: /* DEL */ case 0x152: /* INSERT */ prefix = 0xE0; state = 0; if (key_state & KEY_SHIFT) state = 1; if (key_state & KEY_CONTROL) state = 2; if (key_state & KEY_ALT) { prefix = 0; state = 3; } _putkey (small_keypad_keys[state][scan - 0x147]); _putkey (prefix); Ignore_Wchar_Message = 1; return 0; case 0x3b: /* F1 */ case 0x3c: case 0x3d: case 0x3e: case 0x3f: case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x57: case 0x58: /* F12 */ i = scan - 0x3b; if (i > 9) i -= 0x12; state = 0; if (key_state & KEY_SHIFT) state = 1; if (key_state & KEY_CONTROL) state = 2; if (key_state & KEY_ALT) if (i == 3) /* Alt-F4 */ return DefWindowProc(hWnd, msg, wParam, lParam); else state = 3; _putkey(f_keys[state][i]); _putkey(0); Ignore_Wchar_Message = 1; return 0; } _putkey (c1); _putkey ('O'); _putkey (27); Ignore_Wchar_Message = 1; return 0; } LRESULT CALLBACK JEDWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static int mouse_button_down; PAINTSTRUCT ps; RECT rc; switch (msg) { case WM_CREATE: This_Window.w = hWnd; mouse_button_down = 0; return 0; case WM_SIZE: if (wParam != SIZE_MINIMIZED) { This_Window.width = LOWORD(lParam); This_Window.height = HIWORD(lParam); reset_display(); init_display(1); } break; case WM_PAINT: BeginPaint(This_Window.w, &ps); This_Window.hdc = ps.hdc; This_Window.ndc = 1; cover_exposed_area(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top); EndPaint(This_Window.w, &ps); This_Window.hdc = NULL; This_Window.ndc = 0; break; case WM_ERASEBKGND: GetClientRect(This_Window.w, &rc); FillRect((HDC)wParam, &rc, colors[JNORMAL_COLOR].hbrBG); break; case WM_MENUCHAR: _putkey(wParam); _putkey('\033'); return MAKELONG(0, 1); case WM_CHAR: if (Ignore_Wchar_Message == 0) { if (wParam == 0xE0) _putkey(wParam); _putkey(wParam); break; } return DefWindowProc(hWnd, msg, wParam, lParam); case WM_SYSKEYDOWN: case WM_KEYDOWN: return process_key_down (hWnd, msg, wParam, lParam); case WM_KEYUP: Ignore_Wchar_Message = 0; break; case WM_SYSKEYUP: Ignore_Wchar_Message = 0; return DefWindowProc(hWnd, msg, wParam, lParam); case WM_LBUTTONUP: case WM_MBUTTONUP: case WM_RBUTTONUP: { char c; if (!mouse_button_down) break; switch (msg) { case WM_LBUTTONUP: c = 'l'; break; case WM_MBUTTONUP: c = 'm'; break; case WM_RBUTTONUP: c = 'r'; break; } push_mouse_event(c, LOWORD(lParam), HIWORD(lParam), wParam, MOUSE_RELEASE); mouse_button_down--; break; } case WM_LBUTTONDOWN: case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: { char c; mouse_button_down++; switch (msg) { case WM_LBUTTONDOWN: c = 'l'; break; case WM_MBUTTONDOWN: c = 'm'; break; case WM_RBUTTONDOWN: c = 'r'; break; } push_mouse_event(c, LOWORD(lParam), HIWORD(lParam), wParam, MOUSE_PRESS); break; } case WM_MOUSEMOVE: if (wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) push_mouse_event(0, LOWORD(lParam), HIWORD(lParam), wParam, MOUSE_DRAG); break; case WM_SETFOCUS: case WM_KILLFOCUS: hide_cursor(); This_Window.focus = (msg == WM_SETFOCUS); show_cursor(); break; #if 0 /* This does not quite work when coming back from a shell */ case WM_ACTIVATE: if ((wParam != WA_INACTIVE) && (CBuf != NULL)) check_buffers(); break; #endif case WM_CLOSE: exit_jed(); break; #if !defined(__WIN32__) || !defined (HAS_SUBPROCESSES) case WM_TIMER: if (Display_Time) { JWindow->trashed = 1; update((Line *) NULL, 0, 1); } return 0; #endif case WM_COMMAND: if (wParam < MAX_MENU_ID) { int force = 1; if (Menu_Callbacks[wParam]) { if (is_internal(Menu_Callbacks[wParam])) { char buf[50]; sprintf(buf, "call(\"%s\");", Menu_Callbacks[wParam]); SLang_load_string(buf); } else if (SLang_execute_function(Menu_Callbacks[wParam]) == 0) msg_error(Menu_Callbacks[wParam]); } update_cmd(&force); } return 0; case WM_INITMENUPOPUP: SLang_push_integer(wParam); if (InitPopup_Callback) if (SLang_execute_function(InitPopup_Callback) == 0) msg_error(InitPopup_Callback); return 0; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; } /* FUNCTIONS STOLEN FROM DOS_OS2.C */ void sys_flush (int dummy) { (void) dummy; } /* Delete the file NAME. returns 0 on failure, 1 on sucess * Under OS/2 and DOS, unlink()[UNIX] and remove()[ANSI] are equivalent. */ int sys_delete_file(char *name) { return(1 + remove(name)); } /* Rename the file or directory OLDNAME to NEWNAME. Moving a file * to a different directory on the same drive is possible. * returns 0 on success and -1 on error */ int sys_rename(char *oldname, char *newname) { return(rename(oldname,newname)); } static struct ffblk The_ffblk; static int File_Attr; #define HIDDEN FA_HIDEN #define SYSTEM FA_SYSTEM #define SUBDIR FA_DIREC #define READON FA_RDONLY static char Found_Dir[256]; #define lcase(x) if (((x) >= 'A') && ((x) <= 'Z')) (x) |= 0x20 static void fixup_name(char *file) { int dir; char *p, name[256]; strcpy(file, Found_Dir); strcpy(name, The_ffblk.ff_name); dir = (The_ffblk.ff_attrib & SUBDIR); p = name; while (*p) { lcase(*p); p++; } strcat(file, name); if (dir) strcat(file, "\\"); } int sys_findfirst(char *thefile) { char *f, the_path[256], *file, *f1; char *pat; File_Attr = READON | SUBDIR; file = expand_filename(thefile); f1 = f = extract_file(file); strcpy (Found_Dir, file); Found_Dir[(int) (f - file)] = 0; strcpy(the_path, file); while (*f1 && (*f1 != '*')) f1++; if (! *f1) { while (*f && (*f != '.')) f++; if (*f) strcat(the_path, "*"); else #ifdef __WIN32__ strcat(the_path, "*"); #else strcat(the_path, "*.*"); #endif } pat = the_path; if (!findfirst(pat, &The_ffblk, File_Attr)) { fixup_name(file); strcpy(thefile, file); return(1); } else return 0; } int sys_findnext(char *file) { if (!findnext(&The_ffblk)) { fixup_name(file); return(1); } else return(0); } /* Here we do a find first followed by calling routine to conver time */ unsigned long sys_file_mod_time(char *file) { struct tm t; /* struct tm *local; */ time_t secs; unsigned int dat, tim; File_Attr = READON | SUBDIR; if (!findfirst(file, &The_ffblk, File_Attr)) { tim = The_ffblk.ff_ftime; dat = The_ffblk.ff_fdate; t.tm_min = (tim >> 5) & 63; t.tm_hour = (tim >> 11) & 31; t.tm_sec = 2 * (tim & 31); t.tm_mday = dat & 31; t.tm_mon = (dat >> 5) & 15 - 1; t.tm_year = 80 + ((dat >> 9) & 0x7F); secs = mktime(&t); return((unsigned long) secs); } else return 0; } int sys_chmod(char *file, int what, int *mode, short *dum1, short *dum2) { int flag, m = *mode; (void) dum1; (void) dum2; file = msdos_pinhead_fix_dir (file); if ((m = _chmod(file, what, m)) == -1) { flag = errno; /* Here if carry flag is set */ if (flag == ENOENT) return(0);/* file not found */ return -1; } if (what == 0) { *mode = m; } if (m & 0x10) { /* msg_error("File is a directory."); */ return(2); } return(1); } void flush_output (void) { fflush (stdout); } void get_menubar() { HMENU hmenu = GetMenu(This_Window.w); if (!hmenu) { hmenu = CreateMenu(); SetMenu(This_Window.w, hmenu); DrawMenuBar(This_Window.w); } SLang_push_integer((int) hmenu); } void destroy_menubar() { int i; HMENU hmenu = GetMenu(This_Window.w); if (hmenu) { SetMenu(This_Window.w, NULL); DestroyMenu(hmenu); } for(i = 0; i < MAX_MENU_ID; i++) Menu_Callbacks[i] = NULL; } void create_popup_menu() { HMENU hmenu = CreatePopupMenu(); SLang_push_integer((int) hmenu); } void destroy_menu() { HMENU hmenu; int count, i; int id; if (!SLang_pop_integer((int *)&hmenu)) { count = GetMenuItemCount(hmenu); for(i = 0; i < count; i++) { id = GetMenuItemID(hmenu, i); if (id > 0 && Menu_Callbacks[id] != NULL) { SLFREE(Menu_Callbacks[id]); Menu_Callbacks[id] = NULL; } } if (!DestroyMenu(hmenu)) msg_error("Cannot destroy menu"); } } void append_menu_item() { HMENU hmenu; char *name; int name_flag; int id; char *callback; int callback_flag; if (!SLang_pop_string(&callback, &callback_flag) && !SLang_pop_integer(&id) && !SLang_pop_string(&name, &name_flag) && !SLang_pop_integer((int *)&hmenu)) { if (id >= MAX_MENU_ID) msg_error("Id is too big"); else { if (!AppendMenu(hmenu, MF_STRING, id, name)) msg_error("Cannot append menu item"); else { if (Menu_Callbacks[id]) { char buf[50]; sprintf(buf, "Id %d is already used.", id); msg_error(buf); } else { Menu_Callbacks[id] = SLMALLOC(strlen(callback) + 1); strcpy(Menu_Callbacks[id], callback); } } } if (name_flag) SLFREE(name); if (callback_flag) SLFREE(callback); } } void append_popup_menu() { HMENU hmenu; char *name; int name_flag; HMENU popup; if (!SLang_pop_integer((int *)&popup) && !SLang_pop_string(&name, &name_flag) && !SLang_pop_integer((int *)&hmenu)) { if (!AppendMenu(hmenu, MF_STRING | MF_POPUP, (UINT)popup, name)) msg_error("Cannot append popup menu"); if (name_flag) SLFREE(name); } } void append_separator() { HMENU hmenu; if (!SLang_pop_integer((int *)&hmenu)) { if (!AppendMenu(hmenu, MF_STRING | MF_SEPARATOR, 0, 0)) msg_error("Cannot append separator"); } } void insert_menu_item() { HMENU hmenu; int id; char *name; int name_flag; int idNew; char *callback; int callback_flag; if (!SLang_pop_string(&callback, &callback_flag) && !SLang_pop_integer(&idNew) && !SLang_pop_string(&name, &name_flag) && !SLang_pop_integer(&id) && !SLang_pop_integer((int *)&hmenu)) { if (idNew >= MAX_MENU_ID) msg_error("Id is too big"); else { if (!InsertMenu(hmenu, id, MF_STRING | MF_BYCOMMAND, idNew, name)) msg_error("Cannot insert menu item"); else { if (Menu_Callbacks[idNew]) { char buf[50]; sprintf(buf, "Id %d is already used.", idNew); msg_error(buf); } else { Menu_Callbacks[idNew] = SLMALLOC(strlen(callback) + 1); strcpy(Menu_Callbacks[idNew], callback); } } } if (name_flag) SLFREE(name); if (callback_flag) SLFREE(callback); } } void insert_popup_menu() { HMENU hmenu; int id; char *name; int name_flag; HMENU popup; if (!SLang_pop_integer((int *)&popup) && !SLang_pop_string(&name, &name_flag) && !SLang_pop_integer(&id) && !SLang_pop_integer((int *)&hmenu)) { if (!InsertMenu(hmenu, id, MF_STRING | MF_POPUP | MF_BYCOMMAND, (UINT)popup, name)) msg_error("Cannot insert popup menu"); if (name_flag) SLFREE(name); } } void insert_separator() { HMENU hmenu; int id; if (!SLang_pop_integer(&id) && !SLang_pop_integer((int *)&hmenu)) { if (!InsertMenu(hmenu, id, MF_STRING | MF_SEPARATOR | MF_BYCOMMAND, 0, 0)) msg_error("Cannot insert separator"); } } void insert_menu_item_pos() { HMENU hmenu; int pos; char *name; int name_flag; int idNew; char *callback; int callback_flag; if (!SLang_pop_string(&callback, &callback_flag) && !SLang_pop_integer(&idNew) && !SLang_pop_string(&name, &name_flag) && !SLang_pop_integer(&pos) && !SLang_pop_integer((int *)&hmenu)) { if (idNew >= MAX_MENU_ID) msg_error("Id is too big"); else { if (!InsertMenu(hmenu, pos, MF_STRING | MF_BYPOSITION, idNew, name)) msg_error("Cannot insert menu item"); else { if (Menu_Callbacks[idNew]) { char buf[50]; sprintf(buf, "Id %d is already used.", idNew); msg_error(buf); } else { Menu_Callbacks[idNew] = SLMALLOC(strlen(callback) + 1); strcpy(Menu_Callbacks[idNew], callback); } } } if (name_flag) SLFREE(name); if (callback_flag) SLFREE(callback); } } void insert_popup_menu_pos() { HMENU hmenu; int pos; char *name; int name_flag; HMENU popup; if (!SLang_pop_integer((int *)&popup) && !SLang_pop_string(&name, &name_flag) && !SLang_pop_integer(&pos) && !SLang_pop_integer((int *)&hmenu)) { if (!InsertMenu(hmenu, pos, MF_STRING | MF_POPUP | MF_BYPOSITION, (UINT)popup, name)) msg_error("Cannot insert popup menu"); if (name_flag) SLFREE(name); } } void insert_separator_pos() { HMENU hmenu; int pos; if (!SLang_pop_integer(&pos) && !SLang_pop_integer((int *)&hmenu)) { if (!InsertMenu(hmenu, pos, MF_STRING | MF_SEPARATOR | MF_BYPOSITION, 0, 0)) msg_error("Cannot insert separator"); } } void delete_menu_item() { HMENU hmenu; int id; if (!SLang_pop_integer(&id) && !SLang_pop_integer((int *)&hmenu)) { if (!DeleteMenu(hmenu, id, MF_BYCOMMAND)) msg_error("Cannot delete menu"); else { if (Menu_Callbacks[id]) { SLFREE(Menu_Callbacks[id]); Menu_Callbacks[id] = NULL; } } } } void delete_menu_item_pos() { HMENU hmenu, popup; int pos; int id; if (!SLang_pop_integer(&pos) && !SLang_pop_integer((int *)&hmenu)) { id = GetMenuItemID(hmenu, pos); if ((id > 0) && (Menu_Callbacks[id] != NULL)) { SLFREE(Menu_Callbacks[id]); Menu_Callbacks[id] = NULL; } else if (id == -1) { popup = GetSubMenu(hmenu, pos); SLang_push_integer((int)popup); destroy_menu(); } if (!DeleteMenu(hmenu, pos, MF_BYPOSITION)) msg_error("Cannot delete menu"); } } void get_menu_state() { HMENU hmenu; int id; UINT mstate; int state; if (!SLang_pop_integer(&id) && !SLang_pop_integer((int *)&hmenu)) { if (-1 == (int)(mstate = GetMenuState(hmenu, id, MF_BYCOMMAND))) msg_error("Cannot get menu state"); else { state = 0; if (mstate & MF_ENABLED) state = 1; if (mstate & MF_CHECKED) state |= 2; SLang_push_integer(state); } } } void get_menu_state_pos() { HMENU hmenu; int pos; UINT mstate; int state; if (!SLang_pop_integer(&pos) && !SLang_pop_integer((int *)&hmenu)) { if (-1 == (int)(mstate = GetMenuState(hmenu, pos, MF_BYPOSITION))) msg_error("Cannot get menu state"); else { state = 0; if (mstate & MF_GRAYED) state = 1; if (mstate & MF_CHECKED) state |= 2; SLang_push_integer(state); } } } void get_popup_menu() { HMENU hmenu; int pos; HMENU popup; if (!SLang_pop_integer(&pos) && !SLang_pop_integer((int *)&hmenu)) { popup = GetSubMenu(hmenu, pos); SLang_push_integer((int) popup); } } void check_menu_item() { HMENU hmenu; int id; int flag; if (!SLang_pop_integer(&flag) && !SLang_pop_integer(&id) && !SLang_pop_integer((int *)&hmenu)) { if (-1 == (int) CheckMenuItem(hmenu, id, MF_BYCOMMAND | (flag)?MF_CHECKED:MF_UNCHECKED)) msg_error("Menu item does not exist"); } } void check_menu_item_pos() { HMENU hmenu; int pos; int flag; if (!SLang_pop_integer(&flag) && !SLang_pop_integer(&pos) && !SLang_pop_integer((int *)&hmenu)) { if (!CheckMenuItem(hmenu, pos, MF_BYPOSITION | (flag)?MF_CHECKED:MF_UNCHECKED)) msg_error("Menu item does not exist"); } } void enable_menu_item() { HMENU hmenu; int id; int flag; if (!SLang_pop_integer(&flag) && !SLang_pop_integer(&id) && !SLang_pop_integer((int *)&hmenu)) { if (-1 == EnableMenuItem(hmenu, id, MF_BYCOMMAND | (flag)?MF_ENABLED:MF_GRAYED)) msg_error("Menu item does not exist"); } } void enable_menu_item_pos() { HMENU hmenu; int pos; int flag; if (!SLang_pop_integer(&flag) && !SLang_pop_integer(&pos) && !SLang_pop_integer((int *)&hmenu)) { if (-1 == EnableMenuItem(hmenu, pos, MF_BYPOSITION | (flag)?MF_ENABLED:MF_DISABLED)) msg_error("Menu item does not exist"); } } void redraw_menubar() { DrawMenuBar(This_Window.w); } void set_init_popup_callback() { char *callback; int callback_flag; if (!SLang_pop_string(&callback, &callback_flag)) { if (InitPopup_Callback) SLFREE(InitPopup_Callback); InitPopup_Callback = SLMALLOC(strlen(callback) + 1); strcpy(InitPopup_Callback, callback); if (callback_flag) SLFREE(callback); } } void msw_help() { char *file; int file_flag; char *keyword; int keyword_flag; int partial_keyword; UINT help_type; DWORD dwData; if (!SLang_pop_integer(&partial_keyword) && !SLang_pop_string(&keyword, &keyword_flag) && !SLang_pop_string(&file, &file_flag)) { help_type = (partial_keyword) ? HELP_PARTIALKEY : HELP_KEY; dwData = (DWORD)(LPSTR) keyword; if (*keyword == '\0') { help_type = HELP_CONTENTS; dwData = 0; } if (!WinHelp(This_Window.w, file, help_type, dwData)) { msg_error("Help file not found."); } if (keyword_flag) SLFREE(keyword); if (file_flag) SLFREE(file); } } int (*X_Argc_Argv_Hook)(int, char **); /* the links to functions and variables here */ void (*tt_goto_rc)(int, int) = msw_goto_rc; void (*tt_begin_insert)(void) = msw_begin_insert; void (*tt_end_insert)(void) = msw_end_insert; void (*tt_del_eol)(void) = msw_del_eol; void (*tt_delete_nlines)(int) = msw_delete_nlines; void (*tt_delete_char)(void) = msw_delete_char; void (*tt_erase_line)(void) = msw_erase_line; void (*tt_tt_normal_video)(void) = msw_normal_video; void (*tt_cls)(void) = msw_cls; void (*tt_beep)(void) = msw_beep; void (*tt_reverse_index)(int) = msw_reverse_index; void (*tt_smart_puts)(unsigned short *, unsigned short *, int, int) = msw_smart_puts; void (*tt_write_string)(char *) = msw_write_string; void (*tt_putchar)(char) = msw_putchar; void (*tt_init_video)(void) = msw_init_video; void (*tt_reset_video)(void) = msw_reset_video; void (*tt_normal_video)(void) = msw_normal_video; void (*tt_set_scroll_region)(int, int) = msw_set_scroll_region; void (*tt_reset_scroll_region)(void) = msw_reset_scroll_region; void (*tt_get_terminfo)(void) = msw_get_terminfo; void (*tt_set_color)(int, char *, char *, char *) = msw_set_color; void (*tt_set_color_esc)(int, char *); void (*tt_wide_width)(void) = msw_wide_width; void (*tt_narrow_width)(void) = msw_narrow_width; void (*tt_enable_cursor_keys)(void) = msw_enable_cursor_keys; void (*tt_set_term_vtxxx)(int *) = msw_set_term_vtxxx; int *tt_Ignore_Beep = &JX_Ignore_Beep; int *tt_Use_Ansi_Colors = &JX_Use_Ansi_Colors; int *tt_Term_Cannot_Scroll = &JX_Term_Cannot_Scroll; int *tt_Term_Cannot_Insert = &JX_Term_Cannot_Insert; int *tt_Screen_Rows = &JX_Screen_Rows; int *tt_Screen_Cols = &JX_Screen_Cols; int *tt_Baud_Rate = &JX_Baud_Rate; /* Unused but required. */ int (*X_Open_Mouse_Hook)(void); void (*X_Close_Mouse_Hook)(void); int (*JMouse_Event_Hook)(void); void (*JMouse_Hide_Mouse_Hook)(int); #ifdef __WIN32__ extern int main(int, char **); int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow) { char **argv; int argc; int count; char *pt; int ret; char *command_line = SLMALLOC(strlen(lpszCmdLine) + 7 /* "wjed32" */); (void) hInstance; (void) nCmdShow; #ifdef HAS_SUBPROCESSES InitializeCriticalSection(&Critical_Section); #endif strcpy(command_line, "wjed32 "); strcat(command_line, lpszCmdLine); _hPrev = hPrevInst; while ( (*command_line != '\0') && (*command_line == ' ')) command_line++; /* start on 1st non-space */ pt = command_line; count = 0; while ( *pt != '\0' ) { count++; /* this is an argument */ while ((*pt != '\0') && (*pt != ' ')) pt++; /* advance until a space */ while ( *pt == ' ' ) pt++; /* advance until a non-space */ } argv = (char **) SLMALLOC( (count+3) * sizeof(char *) ); if (argv == NULL ) return 0; /* malloc error */ argc = 0; pt = command_line; while ((argc < count) && (*pt != '\0')) { argv[ argc ] = pt; argc++; while ( *pt != '\0' && *pt != ' ' ) pt++; /* advance until a space */ if ( *pt != '\0' ) *(pt++) = '\0'; /* parse argument here */ while ( *pt == ' ') pt++; /* advance until a non-space */ } argv [ argc ] = (char *) NULL; /* NULL terminated list */ ret = main(argc, argv); SLFREE(command_line); return ret; } #endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.