change SWI stuff to swi directory.

This commit is contained in:
Vitor Santos Costa
2013-03-05 15:50:38 -06:00
parent 263a1a548c
commit a5000dab32
55 changed files with 15540 additions and 3255 deletions

75
swi/console/Makefile.in Normal file
View File

@@ -0,0 +1,75 @@
#
# default base directory for YAP installation
# (EROOT for architecture-dependent files)
#
prefix = @prefix@
exec_prefix = @exec_prefix@
ROOTDIR = $(prefix)
EROOTDIR = @exec_prefix@
#
# where YAP should look for libraries
#
LIBDIR=@libdir@/Yap
#
#
CC=@CC@ -municode -DUNICODE -D_UNICODE
CPPFLAGS=@CPPFLAGS@
CFLAGS= @CFLAGS@ $(DEFS) $(CPPFLAGS) -I$(srcdir) -DRLC_VENDOR="\"YAP\""
#
#
# You shouldn't need to change what follows.
#
INSTALL=@INSTALL@
INSTALL_DATA=@INSTALL_DATA@
INSTALL_PROGRAM=@INSTALL_PROGRAM@
RANLIB=@RANLIB@
AR=@AR@
srcdir=@srcdir@
SOURCES= \
$(srcdir)/complete.c $(srcdir)/console.c \
$(srcdir)/edit.c $(srcdir)/history.c \
$(srcdir)/menu.c
HEADERS= \
$(srcdir)/common.h $(srcdir)/console.h \
$(srcdir)/console_i.h $(srcdir)/history.h \
$(srcdir)/menu.h
OBJECTS= complete.o console.o edit.o history.o menu.o
LIBS=-lgdi32 -lcomdlg32
all: ../../plterm.dll
../../plterm.dll: libplterm.a
$(CC) $(CFLAGS) -shared -o ../../plterm.dll \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive libplterm.a \
-Wl,--no-whole-archive $(LIBS) $(LDFLAGS)
libplterm.a: $(OBJECTS) $(SOURCES) $(HEADERS)
-rm -f libplterm.a
$(AR) rc libplterm.a $(OBJECTS)
$(RANLIB) libplterm.a
install:
clean:
rm -f *.o *~ *.dll
complete.o: $(srcdir)/complete.c
$(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/complete.c -o complete.o
console.o: $(srcdir)/console.c
$(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/console.c -o console.o
history.o: $(srcdir)/history.c
$(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/history.c -o history.o
menu.o: $(srcdir)/menu.c
$(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/menu.c -o menu.o
edit.o: $(srcdir)/edit.c
$(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(srcdir)/edit.c -o edit.o

92
swi/console/README Normal file
View File

@@ -0,0 +1,92 @@
Win32 `Readline Console'
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
Purpose
=======
The `readline console' provides a simple, but reasonable powerful
console window for running standard I/O based applications that may wish
to access Windows functions.
The console window is inspired by both the X11 xterm application and the
GNU readline library. The text is buffered to provide for window
resizing and scroll-back. When reading input by line, an Emacs like
editor is provided for editing the input line. Old input lines are
remembered and used by the history system.
Edit functions
==============
The following edit functions are provided:
Control-A Beginning of line
Control-B Character backward
Control-C Generate interrupt
Control-D Delete character forwards, or end-of-file
Control-E End of line
Control-F Character forwards
Control-I (TAB) Complete (filename, may be programmed)
Control-J (NL) Enter (make line available)
Control-K Delete to end-of-line
Control-M (RET) Enter (make line available)
Control-N Next line in history
Control-P Previous line in history
Control-T Toggle characters around caret
Control-U Empty line
Control-V Paste
Control-Z End-of-file
DEL Delete character forwards
BACKSPACE Delete character backwards
<-, -> Move caret in line, with SHIFT down, move
by word.
Up, down Move in history list
Mouse-bindings:
Left: Start selection, dragging extends the selection.
Double-click selects in `word-mode'. The
selection is placed on the Windows clipboard.
Middle: Paste the Windows clipboard (also Control-V).
Right: Extends the selection.
Compilation:
============
Includes a project file for MSVC 4.2. Please inspect the settings first.
plterm.dll is made from console.c, edit.c and history.c
Settings:
=========
Settings are kept in the Windows registry under the key
Software\<vendor>\<program>\Console
Where
<vendor> is SWI, unless compiled with a different setting for
RLC_VENDOR
<program> is the basename of the program without extension
(i.e. plwin for the program C:\Program
Files\pl\bin\plwin.exe).
Maintained values on this key are:
Name Type Description
================================================================
SaveLines int (200-100000) # lines saved for scrollback
Width int (20-300) # width in characters
Height int (5-100) # height in characters
X int (0-screen-width) # X-position of window
Y int (0-screen-height) # Y-position of window
FaceName str # Font info (settable using
FontFamily int # extension of Windows menu)
FontSize int
FontWeight int
FontCharSet int

View File

@@ -0,0 +1,32 @@
#
# default base directory for YAP installation
#
ROOTDIR = @prefix@
#
# where the binary should be
#
BINDIR = $(ROOTDIR)/bin
#
# where YAP should look for binary libraries
#
LIBDIR=@libdir@/Yap
#
# where YAP should look for architecture-independent Prolog libraries
#
SHAREDIR=$(ROOTDIR)/share
#
#
# You shouldn't need to change what follows.
#
INSTALL=@INSTALL@
INSTALL_DATA=@INSTALL_DATA@
INSTALL_PROGRAM=@INSTALL_PROGRAM@
srcdir=@srcdir@
PROGRAMS= $(srcdir)/clp_events.pl
install: $(PROGRAMS)
mkdir -p $(DESTDIR)$(SHAREDIR)/Yap
mkdir -p $(DESTDIR)$(SHAREDIR)/Yap/clp
for p in $(PROGRAMS); do $(INSTALL_DATA) $$p $(DESTDIR)$(SHAREDIR)/Yap/clp; done

View File

@@ -0,0 +1,89 @@
/* $Id: clp_events.pl,v 1.1 2005-10-28 17:53:27 vsc Exp $
Part of SWI-Prolog
Author: Tom Schrijvers
E-mail: tom.schrijvers@cs.kuleuven.ac.be
WWW: http://www.swi-prolog.org
Copyright (C): 2005, K.U.Leuven
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
As a special exception, if you link this library with other files,
compiled with a Free Software compiler, to produce an executable, this
library does not by itself cause the resulting executable to be covered
by the GNU General Public License. This exception does not however
invalidate any other reasons why the executable file might be covered by
the GNU General Public License.
*/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Module for managing constraint solver events.
%
% Author: Tom Schrijvers
% E-mail: tom.schrijvers@cs.kuleuven.ac.be
% Copyright: 2005, K.U.Leuven
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
:-module(clp_events,
[
notify/2,
subscribe/4,
unsubscribe/2
]).
notify(V,NMod) :-
( get_attr(V,clp_events,List) ->
notify_list(List,NMod)
;
true
).
subscribe(V,NMod,SMod,Goal) :-
( get_attr(V,clp_events,List) ->
put_attr(V,clp_events,[entry(NMod,SMod,Goal)|List])
;
put_attr(V,clp_events,[entry(NMod,SMod,Goal)])
).
unsubscribe(V,SMod) :-
( get_attr(V,clp_events,List) ->
unsubscribe_list(List,SMod,NList),
put_attr(V,clp_events,NList)
;
true
).
notify_list([],_).
notify_list([entry(Mod,_,Goal)|Rest],NMod) :-
( Mod == NMod ->
call(Goal)
;
true
),
notify_list(Rest,NMod).
unsubscribe_list([],_,_).
unsubscribe_list([Entry|Rest],SMod,List) :-
Entry = entry(_,Mod,_),
( Mod == SMod ->
List = Rest
;
List = [Entry|Tail],
unsubscribe_list(Rest,SMod,Tail)
).
attr_unify_hook(_,_).

27
swi/console/common.h Normal file
View File

@@ -0,0 +1,27 @@
/* $Id: common.h,v 1.1 2008-04-01 08:50:48 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define IMODE_SWITCH_CHAR -2
#define RL_CANCELED_CHARP ((TCHAR *)-1)

124
swi/console/complete.c Normal file
View File

@@ -0,0 +1,124 @@
/* $Id: complete.c,v 1.1 2008-03-27 00:41:33 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <windows.h>
#include <tchar.h>
#include "console.h"
#ifndef __TCHAR_DEFINED
typedef wint_t _TINT;
#endif
#ifndef EOS
#define EOS 0
#endif
static TCHAR *completion_chars = TEXT("~:\\/-.");
static size_t
complete_scan_backwards(Line ln, size_t from)
{ while( from > 0 )
{ _TINT c = ln->data[from-1];
if ( rlc_is_word_char(c) ||
_tcschr(completion_chars, c) )
from--;
else
break;
}
return from;
}
static __inline int
close_quote(int c)
{ return (c == '\'' || c == '"') ? c : 0;
}
int
rlc_complete_file_function(RlcCompleteData data)
{ Line ln = data->line;
WIN32_FIND_DATA fdata;
switch(data->call_type)
{ case COMPLETE_INIT:
{ size_t start = complete_scan_backwards(ln, ln->point);
TCHAR *pattern = data->buf_handle;
TCHAR *s = pattern;
size_t n = start;
size_t ld = start;
HANDLE h;
if ( ln->point - start > 200 )
return FALSE;
for( ; n < ln->point; n++)
{ int c = ln->data[n];
if ( c == '/' )
c = '\\';
if ( c == '\\' )
ld = n + 1;
*s++ = c;
}
*s++ = '*';
*s = EOS;
if ( (h=FindFirstFile(pattern, &fdata)) != INVALID_HANDLE_VALUE )
{ data->replace_from = (int)ld;
if ( start > 0 &&
!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
data->quote = close_quote(ln->data[start-1]);
_tcscpy(data->candidate, fdata.cFileName);
data->ptr_handle = h;
data->case_insensitive = TRUE;
data->function = rlc_complete_file_function;
return TRUE;
}
return FALSE;
}
case COMPLETE_ENUMERATE:
{ if ( FindNextFile(data->ptr_handle, &fdata) )
{ _tcscpy(data->candidate, fdata.cFileName);
return TRUE;
}
return FALSE;
}
case COMPLETE_CLOSE:
{ FindClose(data->ptr_handle);
return FALSE;
}
default:
return FALSE;
}
}

3659
swi/console/console.c Normal file

File diff suppressed because it is too large Load Diff

225
swi/console/console.h Normal file
View File

@@ -0,0 +1,225 @@
/* $Id: console.h,v 1.1 2008-04-01 08:45:42 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _CONSOLE_H_INCLUDED
#define _CONSOLE_H_INCLUDED
#ifndef RLC_VENDOR
#define RLC_VENDOR TEXT("SWI")
#endif
#define RLC_TITLE_MAX 256 /* max length of window title */
#ifndef _export
#ifdef _MAKE_DLL
#define _export __declspec(dllexport)
#else
#define _export extern
#endif
#endif
#include <signal.h>
#include <stddef.h>
#if __GNUC__
#include <stdint.h>
#else
#if (_MSC_VER < 1300)
typedef long intptr_t;
typedef unsigned long uintptr_t;
#endif
#endif
#define RLC_APPTIMER_ID 100 /* >=100: application timer */
typedef struct
{ int first;
int last;
int size; /* size of the buffer */
TCHAR *buffer; /* character buffer */
int flags; /* flags for the queue */
} rlc_queue, *RlcQueue;
#define RLC_EOF 0x1 /* Flags on the queue */
typedef struct
{ int mark_x;
int mark_y;
} rlc_mark, *RlcMark;
typedef struct
{ const TCHAR *title; /* window title */
const TCHAR *key; /* Last part of registry-key */
int width; /* # characters(0: default) */
int height; /* # characters (0: default) */
int x; /* # pixels (0: default) */
int y; /* # pixels (0: default) */
int savelines; /* # lines to save (0: default) */
TCHAR face_name[32]; /* font name */
int font_family; /* family id */
int font_size;
int font_weight;
int font_char_set;
} rlc_console_attr;
typedef void * rlc_console; /* console handle */
typedef void (*RlcUpdateHook)(void); /* Graphics update hook */
typedef void (*RlcTimerHook)(int); /* Timer fireing hook */
typedef int (*RlcRenderHook)(WPARAM); /* Render one format */
typedef void (*RlcRenderAllHook)(void); /* Render all formats */
typedef int (*RlcMain)(rlc_console c, int, TCHAR**); /* main() */
typedef void (*RlcInterruptHook)(rlc_console, int); /* Hook for Control-C */
typedef void (*RlcResizeHook)(int, int); /* Hook for window change */
typedef void (*RlcMenuHook)(rlc_console, const TCHAR *id); /* Hook for menu-selection */
typedef void (*RlcFreeDataHook)(uintptr_t data); /* release data */
#if defined(_WINDOWS_) || defined(_WINDOWS_H) /* <windows.h> is included */
/* rlc_color(which, ...) */
#define RLC_WINDOW (0) /* window background */
#define RLC_TEXT (1) /* text color */
#define RLC_HIGHLIGHT (2) /* selected text background */
#define RLC_HIGHLIGHTTEXT (3) /* selected text */
_export HANDLE rlc_hinstance(void); /* hInstance of WinMain() */
_export HWND rlc_hwnd(rlc_console c); /* HWND of console window */
_export int rlc_window_pos(rlc_console c,
HWND hWndInsertAfter,
int x, int y, int w, int h,
UINT flags); /* resize/reposition window */
_export int rlc_main(HANDLE hI, HANDLE hPrevI,
LPTSTR cmd, int show, RlcMain main, HICON icon);
_export void rlc_icon(rlc_console c, HICON icon); /* Change icon */
_export COLORREF rlc_color(rlc_console c, int which, COLORREF color);
typedef LRESULT (*RlcMessageHook)(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam);
_export RlcMessageHook rlc_message_hook(RlcMessageHook hook);
#endif /*_WINDOWS_*/
_export RlcUpdateHook rlc_update_hook(RlcUpdateHook updatehook);
_export RlcTimerHook rlc_timer_hook(RlcTimerHook timerhook);
_export RlcRenderHook rlc_render_hook(RlcRenderHook renderhook);
_export RlcRenderAllHook rlc_render_all_hook(RlcRenderAllHook renderallhook);
_export RlcInterruptHook rlc_interrupt_hook(RlcInterruptHook interrupthook);
_export RlcResizeHook rlc_resize_hook(RlcResizeHook resizehook);
_export RlcMenuHook rlc_menu_hook(RlcMenuHook menuhook);
_export int rlc_copy_output_to_debug_output(int docopy);
_export rlc_console rlc_create_console(rlc_console_attr *attr);
_export void rlc_title(rlc_console c,
TCHAR *title, TCHAR *old, int size);
_export void rlc_yield(void);
_export void rlc_word_char(int chr, int isword);
_export int rlc_is_word_char(int chr);
_export int rlc_iswin32s(void); /* check for Win32S */
_export void rlc_free(void *ptr);
_export void * rlc_malloc(size_t size);
_export void * rlc_realloc(void *ptr, size_t size);
_export size_t rlc_read(rlc_console c, TCHAR *buf, size_t cnt);
_export size_t rlc_write(rlc_console c, TCHAR *buf, size_t cnt);
_export int rlc_close(rlc_console c);
_export int rlc_flush_output(rlc_console c);
_export int getch(rlc_console c);
_export int getche(rlc_console c);
_export int getkey(rlc_console c);
_export int kbhit(rlc_console c);
_export void ScreenGetCursor(rlc_console c, int *row, int *col);
_export void ScreenSetCursor(rlc_console c, int row, int col);
_export int ScreenCols(rlc_console c);
_export int ScreenRows(rlc_console c);
_export int rlc_insert_menu_item(rlc_console c,
const TCHAR *menu,
const TCHAR *label,
const TCHAR *before);
_export int rlc_insert_menu(rlc_console c,
const TCHAR *label,
const TCHAR *before);
/*******************************
* GET/SET VALUES *
*******************************/
#define RLC_APPLICATION_THREAD 0 /* thread-handle of application */
#define RLC_APPLICATION_THREAD_ID 1 /* thread id of application */
#define RLC_VALUE(N) (1000+(N))
_export int rlc_get(rlc_console c, int what,
uintptr_t *val);
_export int rlc_set(rlc_console c, int what,
uintptr_t val,
RlcFreeDataHook hook);
/*******************************
* LINE EDIT STUFF *
*******************************/
typedef struct _line
{ rlc_mark origin; /* origin of edit */
size_t point; /* location of the caret */
size_t size; /* # characters in buffer */
size_t allocated; /* # characters allocated */
size_t change_start; /* start of change */
int complete; /* line is completed */
int reprompt; /* repeat the prompt */
TCHAR *data; /* the data (malloc'ed) */
rlc_console console; /* console I belong to */
} line, *Line;
#define COMPLETE_MAX_WORD_LEN 256
#define COMPLETE_MAX_MATCHES 100
#define COMPLETE_INIT 0
#define COMPLETE_ENUMERATE 1
#define COMPLETE_CLOSE 2
typedef int (*RlcCompleteFunc)(struct _complete_data *);
typedef struct _complete_data
{ Line line; /* line we are completing */
int call_type; /* COMPLETE_* */
int replace_from; /* index to start replacement */
int quote; /* closing quote */
int case_insensitive; /* if TRUE: insensitive match */
TCHAR candidate[COMPLETE_MAX_WORD_LEN];
TCHAR buf_handle[COMPLETE_MAX_WORD_LEN];
RlcCompleteFunc function; /* function for continuation */
void *ptr_handle; /* pointer handle for client */
intptr_t num_handle; /* numeric handle for client */
} rlc_complete_data, *RlcCompleteData;
_export RlcCompleteFunc rlc_complete_hook(RlcCompleteFunc func);
_export TCHAR *read_line(rlc_console console);
_export int rlc_complete_file_function(RlcCompleteData data);
_export void rlc_init_history(rlc_console c, int size);
_export void rlc_add_history(rlc_console c, const TCHAR *line);
_export int rlc_bind(int chr, const char *fname);
#endif /* _CONSOLE_H_INCLUDED */

199
swi/console/console_i.h Normal file
View File

@@ -0,0 +1,199 @@
/* $Id: console_i.h,v 1.1 2008-04-01 08:50:44 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker and Anjo Anjewierden
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Include file to share stuff inside this library.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*******************************
* HISTORY *
*******************************/
typedef struct _history
{ int size; /* size of the history */
int tail; /* oldest position */
int head; /* newest position */
int current; /* for retrieval */
TCHAR ** lines; /* the lines */
} history, *History;
/*******************************
* CONSOLE DATA *
*******************************/
#define ANSI_MAX_ARGC 10 /* Ansi-escape sequence argv */
#define MAXPROMPT 80 /* max size of prompt */
#define OQSIZE 4096 /* output queue size */
#define MAX_USER_VALUES 10 /* max user data-handles */
typedef struct lqueued
{ TCHAR * line; /* Lines in queue */
struct lqueued* next; /* Next in queue */
} lqueued, *LQueued;
typedef struct
{ TCHAR * text; /* the storage */
unsigned short size; /* #characters in line */
unsigned adjusted : 1; /* line has been adjusted? */
unsigned changed : 1; /* line needs redraw */
unsigned softreturn : 1; /* wrapped line */
} text_line, *TextLine;
typedef struct
{ uintptr_t data; /* the data itself */
RlcFreeDataHook hook; /* call when destroying console */
} user_data;
#define RLC_MAGIC 0x3b75df1e /* magic number to verify */
typedef struct
{ int magic;
int height; /* number of lines in buffer */
int width; /* #characters ler line */
int first; /* first line of ring */
int last; /* last line of ring */
int caret_x; /* cursor's x-position */
int caret_y; /* its line */
int window_start; /* start line of the window */
int window_size; /* #lines on the window */
TextLine lines; /* the actual lines */
int sel_unit; /* SEL_CHAR, SEL_WORD, SEL_LINE */
int sel_org_line; /* line origin of the selection */
int sel_org_char; /* char origin of the selection */
int sel_start_line; /* starting line for selection */
int sel_start_char; /* starting char for selection */
int sel_end_line; /* ending line for selection */
int sel_end_char; /* ending char for selection */
int cmdstat; /* for parsing ANSI escape */
int argstat; /* argument status ANSI */
int argc; /* argument count for ANSI */
int argv[ANSI_MAX_ARGC]; /* argument vector for ANSI */
int scaret_x; /* saved-caret X */
int scaret_y; /* saved-caret Y */
HWND window; /* MS-Window window handle */
int has_focus; /* Application has the focus */
HFONT hfont; /* Windows font handle */
int fixedfont; /* Font is fixed */
COLORREF foreground; /* Foreground (text) color */
COLORREF background; /* Background color */
COLORREF sel_foreground; /* Selection foreground */
COLORREF sel_background; /* Selection background */
int cw; /* character width */
int ch; /* character height */
int cb; /* baseline */
int changed; /* changes to the whole screen */
int sb_lines; /* #lines the scrollbar thinks */
int sb_start; /* start-line scrollbar thinks */
int caret_is_shown; /* is caret in the window? */
TCHAR current_title[RLC_TITLE_MAX]; /* window title */
/* status */
rlc_console_attr * create_attributes; /* Creation attributes */
TCHAR *regkey_name; /* last part of key */
int win_x; /* window top-left corner */
int win_y; /* window top-left corner */
/* output queue */
TCHAR output_queue[OQSIZE]; /* The output queue */
int output_queued; /* # characters in the queue */
struct
{ TCHAR *line; /* buffered line */
size_t length; /* length of line */
size_t given; /* how much we passed */
} read_buffer;
/* input queuing */
int imode; /* input mode */
int imodeswitch; /* switching imode */
RlcQueue queue; /* input stream */
LQueued lhead; /* line-queue head */
LQueued ltail; /* line-queue tail */
TCHAR promptbuf[MAXPROMPT]; /* Buffer for building prompt */
TCHAR prompt[MAXPROMPT]; /* The prompt */
int promptlen; /* length of the prompt */
int closing; /* closing status */
int modified_options; /* OPT_ */
history history; /* history for this console */
/* Thread handles */
HANDLE console_thread; /* I/O thread */
HANDLE application_thread; /* The application I work for */
DWORD console_thread_id; /* I/O thread id */
DWORD application_thread_id;
HWND kill_window; /* window in app thread for destroy */
user_data values[MAX_USER_VALUES]; /* associated user data */
} rlc_data, *RlcData;
/*******************************
* DATA *
*******************************/
extern RlcData _rlc_stdio; /* global default console */
/*******************************
* FUNCTIONS *
*******************************/
extern void rlc_assert(const TCHAR *msg);
int rlc_at_head_history(RlcData b);
const TCHAR * rlc_bwd_history(RlcData b);
const TCHAR * rlc_fwd_history(RlcData b);
void rlc_get_mark(rlc_console c, RlcMark mark);
void rlc_goto_mark(rlc_console c, RlcMark mark,
const TCHAR *data, size_t offset);
void rlc_erase_from_caret(rlc_console c);
void rlc_putchar(rlc_console c, int chr);
TCHAR * rlc_read_screen(rlc_console c,
RlcMark from, RlcMark to);
void rlc_update(rlc_console c);
const TCHAR * rlc_prompt(rlc_console c, const TCHAR *prompt);
void rlc_clearprompt(rlc_console c);
/*******************************
* INLINE FUNCTIONS *
*******************************/
#ifdef _DEBUG
#define assert(g) if ( !(g) ) rlc_assert(_T(#g))
#else
#define assert(g) (void)0
#endif
static __inline RlcData
rlc_get_data(rlc_console c)
{ if ( c )
{ RlcData b = c;
assert(b->magic == RLC_MAGIC);
if ( b->magic == RLC_MAGIC )
{ return b;
}
return NULL;
}
return _rlc_stdio;
}

741
swi/console/edit.c Normal file
View File

@@ -0,0 +1,741 @@
/* $Id: edit.c,v 1.1 2008-03-27 00:41:33 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define _MAKE_DLL 1
#undef _export
#include <windows.h>
#include <tchar.h>
#include "console.h"
#include "console_i.h"
#include "common.h"
#include <memory.h>
#include <string.h>
#include <ctype.h>
#ifndef EOF
#define EOF -1
#endif
typedef void (*function)(Line ln, int chr); /* edit-function */
static function dispatch_table[256]; /* general dispatch-table */
static function dispatch_meta[256]; /* ESC-char dispatch */
static RlcCompleteFunc _rlc_complete_function = rlc_complete_file_function;
static void init_line_package(RlcData b);
static void bind_actions(void);
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef EOS
#define EOS 0
#endif
#ifndef ESC
#define ESC 27
#endif
#define COMPLETE_NEWLINE 1
#define COMPLETE_EOF 2
#define ctrl(c) ((c) - '@')
#define META_OFFSET 128
#define meta(c) ((c) + META_OFFSET)
/*******************************
* BUFFER *
*******************************/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
make_room(Line, int room)
Make n-characters space after the point.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static void
make_room(Line ln, size_t room)
{ while ( ln->size + room + 1 > ln->allocated )
{ if ( !ln->data )
{ ln->data = rlc_malloc(256 * sizeof(TCHAR));
ln->allocated = 256;
} else
{ ln->allocated *= 2;
ln->data = rlc_realloc(ln->data, ln->allocated * sizeof(TCHAR));
}
}
memmove(&ln->data[ln->point + room], &ln->data[ln->point],
(ln->size - ln->point)*sizeof(TCHAR));
ln->size += room;
if ( room > 0 )
ln->change_start = min(ln->change_start, ln->point);
}
static void
set_line(Line ln, const TCHAR *s)
{ size_t len = _tcslen(s);
ln->size = ln->point = 0;
make_room(ln, len);
_tcsncpy(ln->data, s, len);
}
static void
terminate(Line ln)
{ if ( !ln->data )
{ ln->data = rlc_malloc(sizeof(TCHAR));
ln->allocated = 1;
}
ln->data[ln->size] = EOS;
}
static void
delete(Line ln, size_t from, size_t len)
{ if ( from < 0 || from > ln->size || len < 0 || from + len > ln->size )
return;
_tcsncpy(&ln->data[from], &ln->data[from+len], ln->size - (from+len));
ln->size -= len;
}
/*******************************
* POSITIONING *
*******************************/
static size_t
back_word(Line ln, size_t from)
{ from = min(from, ln->size);
from = max(0, from);
if ( ln->data )
{ while(!rlc_is_word_char(ln->data[from-1]) && from > 0 )
from--;
while(rlc_is_word_char(ln->data[from-1]) && from > 0 )
from--;
}
return from;
}
static size_t
forw_word(Line ln, size_t from)
{ from = min(from, ln->size);
from = max(0, from);
if ( ln->data )
{ while(!rlc_is_word_char(ln->data[from]) && from < ln->size )
from++;
while(rlc_is_word_char(ln->data[from]) && from < ln->size )
from++;
}
return from;
}
/*******************************
* EDITING FUNCTIONS *
*******************************/
static __inline void
changed(Line ln, size_t from)
{ ln->change_start = min(ln->change_start, from);
}
static void
insert_self(Line ln, int chr)
{ make_room(ln, 1);
ln->data[ln->point++] = chr;
}
static void
backward_delete_character(Line ln, int chr)
{ if ( ln->point > 0 )
{ memmove(&ln->data[ln->point-1], &ln->data[ln->point],
(ln->size - ln->point)*sizeof(TCHAR));
ln->size--;
ln->point--;
}
changed(ln, ln->point);
}
static void
delete_character(Line ln, int chr)
{ if ( ln->point < ln->size )
{ ln->point++;
backward_delete_character(ln, chr);
}
}
static void
backward_character(Line ln, int chr)
{ if ( ln->point > 0 )
ln->point--;
}
static void
forward_character(Line ln, int chr)
{ if ( ln->point < ln->size )
ln->point++;
}
static void
backward_word(Line ln, int chr)
{ ln->point = back_word(ln, ln->point);
}
static void
forward_word(Line ln, int chr)
{ ln->point = forw_word(ln, ln->point);
}
static void
backward_delete_word(Line ln, int chr)
{ size_t from = back_word(ln, ln->point);
memmove(&ln->data[from], &ln->data[ln->point],
(ln->size - ln->point)*sizeof(TCHAR));
ln->size -= ln->point - from;
ln->point = from;
changed(ln, from);
}
static void
forward_delete_word(Line ln, int chr)
{ size_t to = forw_word(ln, ln->point);
memmove(&ln->data[ln->point], &ln->data[to], (ln->size - to)*sizeof(TCHAR));
ln->size -= to - ln->point;
changed(ln, ln->point);
}
static void
transpose_chars(Line ln, int chr)
{ if ( ln->point > 0 && ln->point < ln->size )
{ int c0 = ln->data[ln->point-1];
ln->data[ln->point-1] = ln->data[ln->point];
ln->data[ln->point] = c0;
changed(ln, ln->point-1);
}
}
static void
start_of_line(Line ln, int chr)
{ ln->point = 0;
}
static void
end_of_line(Line ln, int chr)
{ ln->point = ln->size;
}
static void
kill_line(Line ln, int chr)
{ ln->size = ln->point;
changed(ln, ln->size);
}
static void
empty_line(Line ln, int chr)
{ ln->size = ln->point = 0;
changed(ln, 0);
}
static void
enter(Line ln, int chr)
{ ln->point = ln->size;
#ifdef DOS_CRNL
make_room(ln, 2);
ln->data[ln->point++] = '\r';
ln->data[ln->point++] = '\n';
#else
make_room(ln, 1);
ln->data[ln->point++] = '\n';
#endif
terminate(ln);
ln->complete = COMPLETE_NEWLINE;
}
static void
eof(Line ln, int chr)
{ ln->point = ln->size;
terminate(ln);
ln->complete = COMPLETE_EOF;
}
static void
delete_character_or_eof(Line ln, int chr)
{ if ( ln->size == 0 )
{ ln->point = ln->size;
terminate(ln);
ln->complete = COMPLETE_EOF;
} else
delete_character(ln, chr);
}
static void
undefined(Line ln, int chr)
{
}
static void
interrupt(Line ln, int chr)
{ raise(SIGINT);
}
/*******************************
* HISTORY *
*******************************/
static void
add_history(rlc_console c, const TCHAR *data)
{ const TCHAR *s = data;
while(*s && *s <= ' ')
s++;
if ( *s )
rlc_add_history(c, s);
}
static void
backward_history(Line ln, int chr)
{ const TCHAR *h;
if ( rlc_at_head_history(ln->console) && ln->size > 0 )
{ terminate(ln);
add_history(ln->console, ln->data);
}
if ( (h = rlc_bwd_history(ln->console)) )
{ set_line(ln, h);
ln->point = ln->size;
}
}
static void
forward_history(Line ln, int chr)
{ if ( !rlc_at_head_history(ln->console) )
{ const TCHAR *h = rlc_fwd_history(ln->console);
if ( h )
{ set_line(ln, h);
ln->point = ln->size;
}
} else
empty_line(ln, chr);
}
/*******************************
* COMPLETE *
*******************************/
RlcCompleteFunc
rlc_complete_hook(RlcCompleteFunc new)
{ RlcCompleteFunc old = _rlc_complete_function;
_rlc_complete_function = new;
return old;
}
static int
common(const TCHAR *s1, const TCHAR *s2, int insensitive)
{ int n = 0;
if ( !insensitive )
{ while(*s1 && *s1 == *s2)
{ s1++, s2++;
n++;
}
return n;
} else
{ while(*s1)
{ if ( _totlower(*s1) == _totlower(*s2) )
{ s1++, s2++;
n++;
} else
break;
}
return n;
}
}
static void
complete(Line ln, int chr)
{ if ( _rlc_complete_function )
{ rlc_complete_data dbuf;
RlcCompleteData data = &dbuf;
memset(data, 0, sizeof(dbuf));
data->line = ln;
data->call_type = COMPLETE_INIT;
if ( (*_rlc_complete_function)(data) )
{ TCHAR match[COMPLETE_MAX_WORD_LEN];
int nmatches = 1;
size_t ncommon = _tcslen(data->candidate);
size_t patlen = ln->point - data->replace_from;
_tcscpy(match, data->candidate);
data->call_type = COMPLETE_ENUMERATE;
while( (*data->function)(data) )
{ ncommon = common(match, data->candidate, data->case_insensitive);
match[ncommon] = EOS;
nmatches++;
}
data->call_type = COMPLETE_CLOSE;
(*data->function)(data);
delete(ln, data->replace_from, patlen);
ln->point = data->replace_from;
make_room(ln, ncommon);
_tcsncpy(&ln->data[data->replace_from], match, ncommon);
ln->point += ncommon;
if ( nmatches == 1 && data->quote )
insert_self(ln, data->quote);
}
}
}
#define MAX_LIST_COMPLETIONS 256
static void
list_completions(Line ln, int chr)
{ if ( _rlc_complete_function )
{ rlc_complete_data dbuf;
RlcCompleteData data = &dbuf;
memset(data, 0, sizeof(dbuf));
data->line = ln;
data->call_type = COMPLETE_INIT;
if ( (*_rlc_complete_function)(data) )
{ TCHAR *buf[COMPLETE_MAX_MATCHES];
int n, nmatches = 0;
size_t len = _tcslen(data->candidate) + 1;
size_t longest = len;
size_t cols;
buf[nmatches] = rlc_malloc(len*sizeof(TCHAR));
_tcsncpy(buf[nmatches], data->candidate, len);
nmatches++;
data->call_type = COMPLETE_ENUMERATE;
while( (*data->function)(data) )
{ len = _tcslen(data->candidate) + 1;
buf[nmatches] = rlc_malloc(len*sizeof(TCHAR));
_tcsncpy(buf[nmatches], data->candidate, len);
nmatches++;
longest = max(longest, len);
if ( nmatches > COMPLETE_MAX_MATCHES )
{ TCHAR *msg = _T("\r\n! Too many matches\r\n");
while(*msg)
rlc_putchar(ln->console, *msg++);
ln->reprompt = TRUE;
data->call_type = COMPLETE_CLOSE;
(*data->function)(data);
return;
}
}
data->call_type = COMPLETE_CLOSE;
(*data->function)(data);
cols = ScreenCols(ln->console) / longest;
rlc_putchar(ln->console, '\r');
rlc_putchar(ln->console, '\n');
for(n=0; n<nmatches; )
{ TCHAR *s = buf[n];
len = 0;
while(*s)
{ len++;
rlc_putchar(ln->console, *s++);
}
rlc_free(buf[n++]);
if ( n % cols == 0 )
{ rlc_putchar(ln->console, '\r');
rlc_putchar(ln->console, '\n');
} else
{ while( len++ < longest )
rlc_putchar(ln->console, ' ');
}
}
if ( nmatches % cols != 0 )
{ rlc_putchar(ln->console, '\r');
rlc_putchar(ln->console, '\n');
}
ln->reprompt = TRUE;
}
}
}
/*******************************
* REPAINT *
*******************************/
static void
output(rlc_console b, TCHAR *s, size_t len)
{ while(len-- > 0)
{ if ( *s == '\n' )
rlc_putchar(b, '\r');
rlc_putchar(b, *s++);
}
}
static void
update_display(Line ln)
{ if ( ln->reprompt )
{ const TCHAR *prompt = rlc_prompt(ln->console, NULL);
const TCHAR *s = prompt;
rlc_putchar(ln->console, '\r');
while(*s)
rlc_putchar(ln->console, *s++);
rlc_get_mark(ln->console, &ln->origin);
ln->change_start = 0;
ln->reprompt = FALSE;
}
rlc_goto_mark(ln->console, &ln->origin, ln->data, ln->change_start);
output(ln->console,
&ln->data[ln->change_start], ln->size - ln->change_start);
rlc_erase_from_caret(ln->console);
rlc_goto_mark(ln->console, &ln->origin, ln->data, ln->point);
rlc_update(ln->console);
ln->change_start = ln->size;
}
/*******************************
* TOPLEVEL *
*******************************/
TCHAR *
read_line(rlc_console b)
{ line ln;
init_line_package(b);
memset(&ln, 0, sizeof(line));
ln.console = b;
rlc_get_mark(b, &ln.origin);
while(!ln.complete)
{ int c;
rlc_mark m0, m1;
function func;
rlc_get_mark(b, &m0);
if ( (c = getch(b)) == IMODE_SWITCH_CHAR )
return RL_CANCELED_CHARP;
if ( c == EOF )
{ eof(&ln, c);
update_display(&ln);
break;
} else if ( c == ESC )
{ if ( (c = getch(b)) == IMODE_SWITCH_CHAR )
return RL_CANCELED_CHARP;
if ( c > 256 )
func = undefined;
else
func = dispatch_meta[c&0xff];
} else
{ if ( c >= 256 )
func = insert_self;
else
func = dispatch_table[c&0xff];
}
rlc_get_mark(b, &m1);
(*func)(&ln, c);
if ( m0.mark_x != m1.mark_x || m0.mark_y != m1.mark_y )
ln.reprompt = TRUE;
update_display(&ln);
}
rlc_clearprompt(b);
add_history(b, ln.data);
return ln.data;
}
/*******************************
* DISPATCH *
*******************************/
static void
init_dispatch_table()
{ static int done;
if ( !done )
{ int n;
for(n=0; n<32; n++)
dispatch_table[n] = undefined;
for(n=32; n<256; n++)
dispatch_table[n] = insert_self;
for(n=0; n<256; n++)
dispatch_meta[n] = undefined;
bind_actions();
done = TRUE;
}
}
static void
init_line_package(RlcData b)
{ init_dispatch_table();
rlc_init_history(b, 50);
}
/*******************************
* BIND *
*******************************/
typedef struct _action
{ char *name;
function function;
unsigned char keys[4];
} action, *Action;
#define ACTION(n, f, k) { n, f, k }
static action actions[] = {
ACTION("insert_self", insert_self, ""),
ACTION("backward_delete_character", backward_delete_character, "\b"),
ACTION("complete", complete, "\t"),
ACTION("enter", enter, "\r\n"),
ACTION("start_of_line", start_of_line, {ctrl('A')}),
ACTION("backward_character", backward_character, {ctrl('B')}),
ACTION("interrupt", interrupt, {ctrl('C')}),
ACTION("end_of_line", end_of_line, {ctrl('E')}),
ACTION("forward_character", forward_character, {ctrl('F')}),
ACTION("transpose_chars", transpose_chars, {ctrl('T')}),
ACTION("kill_line", kill_line, {ctrl('K')}),
ACTION("backward_history", backward_history, {ctrl('P')}),
ACTION("forward_history", forward_history, {ctrl('N')}),
ACTION("empty_line", empty_line, {ctrl('U')}),
ACTION("eof", eof, {ctrl('Z')}),
ACTION("delete_character_or_eof", delete_character_or_eof, {ctrl('D')}),
ACTION("delete_character", delete_character, {127}),
{ "forward_word", forward_word, {meta(ctrl('F')), meta('f')}},
{ "backward_word", backward_word, {meta(ctrl('B')), meta('b')}},
{ "forward_delete_word", forward_delete_word, {meta(127), meta('d')}},
ACTION("list_completions", list_completions, {meta('?')}),
ACTION("backward_delete_word", backward_delete_word, {meta('\b')}),
ACTION(NULL, NULL, "")
};
int
rlc_bind(int chr, const char *fname)
{ if ( chr >= 0 && chr <= 256 )
{ Action a = actions;
for( ; a->name; a++ )
{ if ( strcmp(a->name, fname) == 0 )
{ if ( chr > META_OFFSET )
dispatch_meta[chr-META_OFFSET] = a->function;
else
dispatch_table[chr] = a->function;
return TRUE;
}
}
}
return FALSE;
}
static void
bind_actions()
{ Action a = actions;
for( ; a->name; a++ )
{ unsigned char *k = a->keys;
for( ; *k; k++ )
{ int chr = *k & 0xff;
if ( chr > META_OFFSET )
dispatch_meta[chr-META_OFFSET] = a->function;
else
dispatch_table[chr] = a->function;
}
}
}

160
swi/console/history.c Normal file
View File

@@ -0,0 +1,160 @@
/* $Id: history.c,v 1.1 2008-03-27 00:41:33 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define _MAKE_DLL 1
#undef _export
#include <windows.h>
#include <tchar.h>
#include "console.h" /* public stuff */
#include "console_i.h" /* internal stuff */
#include <string.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
static __inline int
next(RlcData b, int i)
{ if ( ++i == b->history.size )
return 0;
return i;
}
static __inline int
prev(RlcData b, int i)
{ if ( --i < 0 )
return b->history.size-1;
return i;
}
void
rlc_init_history(rlc_console c, int size)
{ RlcData b = rlc_get_data(c);
int oldsize;
int i;
if ( b->history.lines )
{ b->history.lines = rlc_realloc(b->history.lines, sizeof(TCHAR *) * size);
oldsize = b->history.size;
} else
{ b->history.lines = rlc_malloc(sizeof(TCHAR *) * size);
oldsize = 0;
}
for(i=oldsize; i<size; i++)
b->history.lines[i] = NULL;
b->history.size = size;
b->history.current = -1;
}
void
rlc_add_history(rlc_console c, const TCHAR *line)
{ RlcData b = rlc_get_data(c);
if ( b->history.size )
{ int i = next(b, b->history.head);
size_t len = _tcslen(line);
while(*line && *line <= ' ') /* strip leading white-space */
line++;
len = _tcslen(line);
/* strip trailing white-space */
while ( len > 0 && line[len-1] <= ' ' )
len--;
if ( len == 0 )
{ b->history.current = -1;
return;
}
if ( b->history.lines[b->history.head] &&
_tcsncmp(b->history.lines[b->history.head], line, len) == 0 )
{ b->history.current = -1;
return; /* same as last line added */
}
if ( i == b->history.tail ) /* this one is lost */
b->history.tail = next(b, b->history.tail);
b->history.head = i;
b->history.current = -1;
if ( b->history.lines[i] )
b->history.lines[i] = rlc_realloc(b->history.lines[i],
(len+1)*sizeof(TCHAR));
else
b->history.lines[i] = rlc_malloc((len+1)*sizeof(TCHAR));
if ( b->history.lines[i] )
{ _tcsncpy(b->history.lines[i], line, len);
b->history.lines[i][len] = '\0';
}
}
}
int
rlc_at_head_history(RlcData b)
{ return b->history.current == -1 ? TRUE : FALSE;
}
const TCHAR *
rlc_bwd_history(RlcData b)
{ if ( b->history.size )
{ if ( b->history.current == -1 )
b->history.current = b->history.head;
else if ( b->history.current == b->history.tail )
return NULL;
else
b->history.current = prev(b, b->history.current);
return b->history.lines[b->history.current];
}
return NULL;
}
const TCHAR *
rlc_fwd_history(RlcData b)
{ if ( b->history.size && b->history.current != -1 )
{ const TCHAR *s;
b->history.current = next(b, b->history.current);
s = b->history.lines[b->history.current];
if ( b->history.current == b->history.head )
b->history.current = -1;
return s;
}
return NULL;
}

30
swi/console/history.h Normal file
View File

@@ -0,0 +1,30 @@
/* $Id: history.h,v 1.1 2008-04-01 08:52:50 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* history.c */
void rlc_init_history(int auto_add, int size);
void rlc_add_history(const TCHAR *line);
int rlc_at_head_history(void);
const TCHAR * rlc_bwd_history(void);
const TCHAR * rlc_fwd_history(void);

299
swi/console/menu.c Normal file
View File

@@ -0,0 +1,299 @@
/* $Id: menu.c,v 1.1 2008-03-27 00:41:33 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <windows.h>
#include <tchar.h>
#define _MAKE_DLL
#include "console.h"
#include "console_i.h"
#include "menu.h"
#ifndef EOS
#define EOS 0
#endif
#define streq(s,q) (_tcscmp((s), (q)) == 0)
static TCHAR **menuids;
static int nmenus;
static int nmenualloc;
static struct rl_item
{ UINT id;
const TCHAR *name;
} rl_items[] =
{ { IDM_EXIT, _T("&Exit") },
{ IDM_CUT, _T("&Cut") },
{ IDM_COPY, _T("&Copy") },
{ IDM_PASTE, _T("&Paste") },
{ IDM_BREAK, _T("&Interrupt") },
{ IDM_FONT, _T("&Font ...") },
{ 0, NULL }
};
static UINT
lookupMenuLabel(const TCHAR *label)
{ int i;
size_t llen;
struct rl_item *builtin;
for(builtin = rl_items; builtin->id; builtin++)
{ if ( streq(builtin->name, label) )
return builtin->id;
}
for(i=0; i<nmenus; i++)
{ if ( streq(menuids[i], label) )
return i + IDM_USER;
}
if ( nmenus + 1 > nmenualloc )
{ if ( nmenualloc )
{ nmenualloc *= 2;
menuids = rlc_realloc(menuids, nmenualloc*sizeof(TCHAR *));
} else
{ nmenualloc = 32;
menuids = rlc_malloc(nmenualloc*sizeof(TCHAR *));
}
}
llen = _tcslen(label);
menuids[nmenus] = rlc_malloc((llen+1)*sizeof(TCHAR));
_tcsncpy(menuids[nmenus], label, llen+1);
return nmenus++ + IDM_USER;
}
const TCHAR *
lookupMenuId(UINT id)
{ struct rl_item *builtin;
if ( id >= IDM_USER && (int)id - IDM_USER < nmenus )
return menuids[id-IDM_USER];
for(builtin = rl_items; builtin->id; builtin++)
{ if ( builtin->id == id )
return builtin->name;
}
return NULL;
}
int
insertMenu(HMENU in, const TCHAR *label, const TCHAR *before)
{ if ( !before )
{ if ( !label )
AppendMenu(in, MF_SEPARATOR, 0, NULL);
else
{ UINT id = lookupMenuLabel(label);
AppendMenu(in, MF_STRING, id, label);
}
} else
{ UINT bid = lookupMenuLabel(before);
MENUITEMINFO info;
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.fMask = MIIM_TYPE;
if ( label )
{ info.fType = MFT_STRING;
info.fMask |= MIIM_ID;
info.wID = lookupMenuLabel(label);
info.dwTypeData = (TCHAR *)label;
info.cch = (int)_tcslen(label);
} else
{ info.fType = MFT_SEPARATOR;
}
InsertMenuItem(in, bid, FALSE, &info);
}
return TRUE;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Find popup with given name.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static HMENU
findPopup(RlcData b, const TCHAR *name, int *pos)
{ HMENU mb = GetMenu(rlc_hwnd(b));
if ( mb )
{ int i;
MENUITEMINFO info;
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.fMask = MIIM_TYPE;
for(i=0; ; i++)
{ MENUITEMINFO info;
TCHAR nbuf[MAXLABELLEN];
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.fMask = MIIM_TYPE|MIIM_SUBMENU;
info.dwTypeData = nbuf;
info.cch = sizeof(nbuf);
if ( !GetMenuItemInfo(mb, i, TRUE, &info) )
return NULL;
if ( info.fType == MF_STRING )
{ if ( streq(name, nbuf) )
{ if ( pos )
*pos = i;
return info.hSubMenu;
}
}
}
}
return 0;
}
static void
append_builtin(HMENU menu, UINT id)
{ AppendMenu(menu, MF_STRING, id, lookupMenuId(id));
}
void
rlc_add_menu_bar(HWND cwin)
{ HMENU menu = CreateMenu();
HMENU file = CreatePopupMenu();
HMENU edit = CreatePopupMenu();
HMENU settings = CreatePopupMenu();
HMENU run = CreatePopupMenu();
append_builtin(file, IDM_EXIT);
/*append_builtin(edit, IDM_CUT);*/
append_builtin(edit, IDM_COPY);
append_builtin(edit, IDM_PASTE);
append_builtin(settings, IDM_FONT);
append_builtin(run, IDM_BREAK);
AppendMenu(menu, MF_POPUP, (UINT)file, _T("&File"));
AppendMenu(menu, MF_POPUP, (UINT)edit, _T("&Edit"));
AppendMenu(menu, MF_POPUP, (UINT)settings, _T("&Settings"));
AppendMenu(menu, MF_POPUP, (UINT)run, _T("&Run"));
SetMenu(cwin, menu);
}
/*******************************
* EXTERNAL *
*******************************/
#define MEN_MAGIC 0x6c4a58e0
void
rlc_menu_action(rlc_console c, menu_data *data)
{ RlcData b = rlc_get_data(c);
if ( !data || !data->magic == MEN_MAGIC )
return;
if ( data->menu ) /* rlc_insert_menu_item() */
{ HMENU popup;
if ( (popup = findPopup(b, data->menu, NULL)) )
data->rc = insertMenu(popup, data->label, data->before);
else
data->rc = FALSE;
} else /* insert_menu() */
{ HMENU mb;
HWND hwnd = rlc_hwnd(c);
if ( !(mb = GetMenu(hwnd)) )
{ data->rc = FALSE;
return;
}
if ( !findPopup(b, data->label, NULL) ) /* already there */
{ MENUITEMINFO info;
int bid = -1;
if ( data->before )
findPopup(b, data->before, &bid);
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.fMask = MIIM_TYPE|MIIM_SUBMENU;
info.fType = MFT_STRING;
info.hSubMenu = CreatePopupMenu();
info.dwTypeData = (TCHAR *)data->label;
info.cch = (int)_tcslen(data->label);
InsertMenuItem(mb, bid, TRUE, &info);
/* force redraw; not automatic! */
DrawMenuBar(hwnd);
}
data->rc = TRUE;
}
}
int
rlc_insert_menu(rlc_console c, const TCHAR *label, const TCHAR *before)
{ HWND hwnd = rlc_hwnd(c);
menu_data data;
data.magic = MEN_MAGIC;
data.menu = NULL;
data.label = label;
data.before = before;
SendMessage(hwnd, WM_RLC_MENU, 0, (LPARAM)&data);
return data.rc;
}
int
rlc_insert_menu_item(rlc_console c,
const TCHAR *menu, const TCHAR *label, const TCHAR *before)
{ HWND hwnd = rlc_hwnd(c);
menu_data data;
data.magic = MEN_MAGIC;
data.menu = menu;
data.label = label;
data.before = before;
SendMessage(hwnd, WM_RLC_MENU, 0, (LPARAM)&data);
return data.rc;
}

49
swi/console/menu.h Normal file
View File

@@ -0,0 +1,49 @@
/* $Id: menu.h,v 1.1 2008-04-01 08:50:44 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* see also console.c */
#define WM_RLC_MENU WM_USER+15 /* Insert a menu */
#define IDM_USER 100 /* reserve below 100 */
#define MAXLABELLEN 256 /* max length of menu-item label */
#define IDM_EXIT 10
#define IDM_CUT 11
#define IDM_COPY 12
#define IDM_PASTE 13
#define IDM_BREAK 14
#define IDM_FONT 15
typedef struct menu_data
{ intptr_t magic; /* safety */
const TCHAR *menu; /* menu to operate on */
const TCHAR *label; /* new label */
const TCHAR *before; /* add before this one */
int rc; /* result */
} menu_data;
const TCHAR *lookupMenuId(UINT id);
void rlc_add_menu_bar(HWND win);
void rlc_menu_action(rlc_console c, struct menu_data *data);

89
swi/console/registry.c Normal file
View File

@@ -0,0 +1,89 @@
/* $Id: registry.c,v 1.1 2008-03-27 00:41:33 vsc Exp $
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: jan@swi.psy.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2002, University of Amsterdam
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <windows.h>
#include "registry.h"
#define MAXKEYLEN 256
#define MAXKEYPATHLEN 1024
static TCHAR _rlc_regbase[MAXKEYPATHLEN] = TEXT("current_user/PrologConsole");
static HKEY
reg_open_key(const TCHAR *path, HKEY parent, REGSAM access)
{ TCHAR buf[MAXKEYLEN];
TCHAR *sep;
if ( *path )
return parent;
for(sep = path; *sep && *sep != '/' && *sep != '\\'; sep++)
;
strncpy(buf, path, sep-path);
if ( *sep )
sep++;
if ( strchr(sep, '/') || strchr(sep, '\\') ) /* there is more */
{ HKEY sub;
if ( RegOpenKeyEx(parent, buf, 0L, KEY_READ, &sub) != ERROR_SUCCESS )
return NULL;
return reg_open_key(sep, sub, access);
} else
{ HKEY sub;
if ( RegOpenKeyEx(parent, buf, 0L, KEY_READ, access) != ERROR_SUCCESS )
return NULL;
return sub;
}
}
HKEY
RegOpenKeyFromPath(const TCHAR *path, REGSAM access)
{ TCHAR buf[MAXKEYLEN];
TCHAR *sep;
HKEY root;
for(sep = path; *sep && *sep != '/' && *sep != '\\'; sep++)
;
strncpy(buf, path, sep-path);
if ( streq(buf, TEXT("classes_root")) )
root = HKEY_CLASSES_ROOT;
else if ( streq(buf, TEXT("current_user")) )
root = HKEY_CURRENT_USER;
else if ( streq(buf, TEXT("local_machine")) )
root = HKEY_LOCAL_MACHINE;
else if ( streq(buf, TEXT("users")) )
root = HKEY_USERS;
else
return NULL;
if ( *sep )
sep++;
return reg_open_key(sep, root, REGSAM);
}