mirror of
https://github.com/VARCem/PDCurses.git
synced 2026-09-25 00:05:16 +00:00
X11 reorg: Combined pdcx11.c and process/x11.c into x11.c; combined
process/x11common.c and process/x11curses.c into pdcx11.c. This way, "pdc" is consistently used as a prefix for files with functions in the curses process, while x11.c contains all the code for the X process. To Do: Break up x11.c along other lines? And much more.
This commit is contained in:
@@ -77,7 +77,7 @@ $(ZIPFILE):
|
||||
pdcurses/*.c demos/README demos/*.c demos/*.h panel/README \
|
||||
panel/*.c dos/README dos/*.c dos/*.h dos/*.rsp dos/*.mak \
|
||||
dos/*.lrf os2/README os2/*.c os2/*.mak os2/*.lrf os2/*.def \
|
||||
x11/README x11/*.c x11/*.xbm x11/*.h x11/process/*.c \
|
||||
x11/README x11/*.c x11/*.xbm x11/*.h \
|
||||
win32/README win32/*.c win32/*.mak win32/*.lrf win32/*.def \
|
||||
win32/*.ico win32/*.rc doc/*.man tools/manext.c \
|
||||
x11/Makefile.* tools/Makefile.in
|
||||
@@ -101,7 +101,7 @@ zip: $(ZIPFILE)
|
||||
$(PDC_DIR)/os2/README $(PDC_DIR)/os2/*.c $(PDC_DIR)/os2/*.mak \
|
||||
$(PDC_DIR)/os2/*.lrf $(PDC_DIR)/os2/*.def $(PDC_DIR)/x11/README \
|
||||
$(PDC_DIR)/x11/*.c $(PDC_DIR)/x11/*.xbm $(PDC_DIR)/x11/*.h \
|
||||
$(PDC_DIR)/x11/process/*.c $(PDC_DIR)/x11/Makefile.* \
|
||||
$(PDC_DIR)/x11/Makefile.* \
|
||||
$(PDC_DIR)/win32/README $(PDC_DIR)/win32/*.c \
|
||||
$(PDC_DIR)/win32/*.mak $(PDC_DIR)/win32/*.lrf \
|
||||
$(PDC_DIR)/win32/*.def $(PDC_DIR)/win32/*.ico \
|
||||
|
||||
@@ -10,7 +10,6 @@ THIS = Makefile
|
||||
@SET_MAKE@
|
||||
|
||||
osdir = @srcdir@
|
||||
x11dir = $(osdir)/process
|
||||
srcdir = $(osdir)/../pdcurses
|
||||
pandir = $(osdir)/../panel
|
||||
|
||||
@@ -24,8 +23,7 @@ PDCURSES_HOME =$(srcdir)/..
|
||||
PDCURSES_CONFIG_H =../config.h
|
||||
PDCURSES_CURSES_H =$(PDCURSES_HOME)/curses.h
|
||||
PDCURSES_CURSPRIV_H =$(PDCURSES_HOME)/curspriv.h
|
||||
PDCURSES_HEADERS =$(PDCURSES_CONFIG_H) $(PDCURSES_CURSES_H)
|
||||
$(PDCURSES_CURSPRIV_H)
|
||||
PDCURSES_HEADERS =$(PDCURSES_CONFIG_H) $(PDCURSES_CURSES_H) $(PDCURSES_CURSPRIV_H)
|
||||
PDCURSES_X11_H =$(osdir)/pdcx11.h
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
@@ -49,7 +47,7 @@ CC = @CC@
|
||||
CFLAGS = @CFLAGS@ $(DYN_COMP)
|
||||
|
||||
INCDIR = $(srcdir)
|
||||
CPPFLAGS = -I$(INCDIR) -I$(srcdir)/.. -I.. @DEFS@ -DXCURSES @SYS_DEFS@ -I$(osdir) -I$(x11dir)
|
||||
CPPFLAGS = -I$(INCDIR) -I$(srcdir)/.. -I.. @DEFS@ -DXCURSES @SYS_DEFS@ -I$(osdir)
|
||||
|
||||
CCFLAGS = -c $(CFLAGS) $(CPPFLAGS) @MH_XINC_DIR@
|
||||
|
||||
@@ -85,7 +83,7 @@ scroll.o slk.o termattr.o terminfo.o touch.o util.o window.o
|
||||
PDCOBJS = pdcclip.o pdcdebug.o pdcdisp.o pdcgetsc.o pdckbd.o \
|
||||
pdckey.o pdcscrn.o pdcsetsc.o pdcutil.o pdcwin.o
|
||||
|
||||
X11OBJS = pdcx11.o x11curses.o x11common.o x11.o sb.o ScrollBox.o
|
||||
X11OBJS = pdcx11.o x11.o sb.o ScrollBox.o
|
||||
|
||||
PANOBJS = panel.o
|
||||
|
||||
@@ -257,14 +255,8 @@ ScrollBox.o: $(osdir)/ScrollBox.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
sb.o: $(osdir)/sb.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(osdir)/sb.c
|
||||
|
||||
x11common.o: $(x11dir)/x11common.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(x11dir)/x11common.c
|
||||
|
||||
x11.o: $(x11dir)/x11.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(x11dir)/x11.c
|
||||
|
||||
x11curses.o: $(x11dir)/x11curses.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(x11dir)/x11curses.c
|
||||
x11.o: $(osdir)/x11.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(osdir)/x11.c
|
||||
|
||||
|
||||
panel.o: $(pandir)/panel.c $(PDCURSES_HEADERS) $(PDCURSES_HOME)/panel.h
|
||||
|
||||
@@ -10,7 +10,6 @@ THIS = Makefile
|
||||
@SET_MAKE@
|
||||
|
||||
osdir = @srcdir@
|
||||
x11dir = $(osdir)/process
|
||||
srcdir = $(osdir)/../pdcurses
|
||||
pandir = $(osdir)/../panel
|
||||
demodir = $(osdir)/../demos
|
||||
@@ -46,7 +45,7 @@ DYNAMIC_LDFLAGS = @DYNAMIC_LDFLAGS@ $(EEXTRA)
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@
|
||||
|
||||
CPPFLAGS = -I$(PDCURSES_HOME) -I$(srcdir) @DEFS@ -DXCURSES @SYS_DEFS@ -I$(osdir) -I$(x11dir)
|
||||
CPPFLAGS = -I$(PDCURSES_HOME) -I$(srcdir) @DEFS@ -DXCURSES @SYS_DEFS@ -I$(osdir)
|
||||
|
||||
CCFLAGS = -c $(CFLAGS) $(CPPFLAGS) @MH_XINC_DIR@
|
||||
|
||||
@@ -96,7 +95,7 @@ scroll.o slk.o termattr.o terminfo.o touch.o util.o window.o
|
||||
PDCOBJS = pdcclip.o pdcdebug.o pdcdisp.o pdcgetsc.o pdckbd.o \
|
||||
pdckey.o pdcscrn.o pdcsetsc.o pdcutil.o pdcwin.o
|
||||
|
||||
X11OBJS = pdcx11.o x11curses.o x11common.o x11.o sb.o ScrollBox.o
|
||||
X11OBJS = pdcx11.o x11.o sb.o ScrollBox.o
|
||||
|
||||
PANOBJS = panel.o
|
||||
|
||||
@@ -111,8 +110,7 @@ window.sho
|
||||
PDCSHOBJS = pdcclip.sho pdcdebug.sho pdcdisp.sho pdcgetsc.sho pdckbd.sho \
|
||||
pdckey.sho pdcscrn.sho pdcsetsc.sho pdcutil.sho pdcwin.sho
|
||||
|
||||
X11SHOBJS = pdcx11.sho x11curses.sho x11common.sho x11.sho sb.sho \
|
||||
ScrollBox.sho
|
||||
X11SHOBJS = pdcx11.sho x11.sho sb.sho ScrollBox.sho
|
||||
|
||||
|
||||
SHOFILES = $(LIBSHOBJS) $(PDCSHOBJS) $(X11SHOBJS)
|
||||
@@ -283,14 +281,8 @@ ScrollBox.o: $(osdir)/ScrollBox.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
sb.o: $(osdir)/sb.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(osdir)/sb.c
|
||||
|
||||
x11common.o: $(x11dir)/x11common.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(x11dir)/x11common.c
|
||||
|
||||
x11.o: $(x11dir)/x11.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(x11dir)/x11.c
|
||||
|
||||
x11curses.o: $(x11dir)/x11curses.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(x11dir)/x11curses.c
|
||||
x11.o: $(osdir)/x11.c $(PDCURSES_HEADERS) $(PDCURSES_X11_H)
|
||||
$(CC) $(CCFLAGS) -o $@ $(osdir)/x11.c
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
@@ -606,21 +598,9 @@ sb.sho: $(osdir)/sb.c $(PDCURSES_HEADERS)
|
||||
$(O2SHO)
|
||||
$(SAVE2O)
|
||||
|
||||
x11common.sho: $(x11dir)/x11common.c $(PDCURSES_HEADERS)
|
||||
x11.sho: $(osdir)/x11.c $(PDCURSES_HEADERS)
|
||||
$(O2SAVE)
|
||||
$(CC) $(CCFLAGS) $(DYN_COMP) $(CC2O) $(x11dir)/x11common.c
|
||||
$(O2SHO)
|
||||
$(SAVE2O)
|
||||
|
||||
x11.sho: $(x11dir)/x11.c $(PDCURSES_HEADERS)
|
||||
$(O2SAVE)
|
||||
$(CC) $(CCFLAGS) $(DYN_COMP) $(CC2O) $(x11dir)/x11.c
|
||||
$(O2SHO)
|
||||
$(SAVE2O)
|
||||
|
||||
x11curses.sho: $(x11dir)/x11curses.c $(PDCURSES_HEADERS)
|
||||
$(O2SAVE)
|
||||
$(CC) $(CCFLAGS) $(DYN_COMP) $(CC2O) $(x11dir)/x11curses.c
|
||||
$(CC) $(CCFLAGS) $(DYN_COMP) $(CC2O) $(osdir)/x11.c
|
||||
$(O2SHO)
|
||||
$(SAVE2O)
|
||||
|
||||
|
||||
3002
x11/pdcx11.c
3002
x11/pdcx11.c
File diff suppressed because it is too large
Load Diff
@@ -1,912 +0,0 @@
|
||||
/************************************************************************
|
||||
* This file is part of PDCurses. PDCurses is public domain software; *
|
||||
* you may use it for any purpose. This software is provided AS IS with *
|
||||
* NO WARRANTY whatsoever. *
|
||||
* *
|
||||
* If you use PDCurses in an application, an acknowledgement would be *
|
||||
* appreciated, but is not mandatory. If you make corrections or *
|
||||
* enhancements to PDCurses, please forward them to the current *
|
||||
* maintainer for the benefit of other users. *
|
||||
* *
|
||||
* No distribution of modified PDCurses code may be made under the name *
|
||||
* "PDCurses", except by the current maintainer. (Although PDCurses is *
|
||||
* public domain, the name is a trademark.) *
|
||||
* *
|
||||
* See the file maintain.er for details of the current maintainer. *
|
||||
************************************************************************/
|
||||
|
||||
#include "pdcx11.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
RCSID("$Id: x11.c,v 1.59 2006/07/21 04:09:29 wmcbrine Exp $");
|
||||
|
||||
int visible_cursor = 0;
|
||||
int windowEntered = 1;
|
||||
static char *XCursesProgramName;
|
||||
|
||||
void XCursesStructureNotify(Widget, XtPointer, XEvent *, Boolean *);
|
||||
void XCursesRequestorCallbackForGetSelection(Widget, XtPointer, Atom *, Atom *,
|
||||
XtPointer, unsigned long *, int *);
|
||||
RETSIGTYPE XCursesSignalHandler(int);
|
||||
|
||||
void XCursesExitXCursesProcess(int rc, int sig, char *msg)
|
||||
{
|
||||
if (rc || sig)
|
||||
fprintf(stderr,
|
||||
"%s:XCursesExitXCursesProcess() - called: rc:%d sig:%d <%s>\n",
|
||||
XCLOGMSG, rc, sig, msg);
|
||||
|
||||
shmdt((char *)SP);
|
||||
shmdt((char *)Xcurscr);
|
||||
shmctl(shmidSP, IPC_RMID, 0);
|
||||
shmctl(shmid_Xcurscr, IPC_RMID, 0);
|
||||
|
||||
XCursesEndwin();
|
||||
|
||||
shutdown(display_sock, 2);
|
||||
close(display_sock);
|
||||
|
||||
shutdown(exit_sock, 2);
|
||||
close(exit_sock);
|
||||
|
||||
shutdown(key_sock, 2);
|
||||
close(key_sock);
|
||||
|
||||
if (sig)
|
||||
kill(otherpid, sig); /* to kill parent process */
|
||||
|
||||
_exit(rc);
|
||||
}
|
||||
|
||||
/* This function draws those portions of the screen that have changed. */
|
||||
|
||||
static int XCursesRefreshScreen(void)
|
||||
{
|
||||
int row, start_col, num_cols;
|
||||
|
||||
PDC_LOG(("%s:XCursesRefreshScreen() - called:\n", XCLOGMSG));
|
||||
|
||||
for (row = 0; row < XCursesLINES; row++)
|
||||
{
|
||||
num_cols = (int)*(Xcurscr + XCURSCR_LENGTH_OFF + row);
|
||||
|
||||
if (num_cols != 0)
|
||||
{
|
||||
get_line_lock(row);
|
||||
|
||||
start_col = (int)*(Xcurscr + XCURSCR_START_OFF + row);
|
||||
|
||||
XCursesDisplayText((const chtype *)(Xcurscr +
|
||||
XCURSCR_Y_OFF(row) + (start_col *
|
||||
sizeof(chtype))), row, start_col,
|
||||
num_cols, FALSE);
|
||||
|
||||
*(Xcurscr + XCURSCR_LENGTH_OFF + row) = 0;
|
||||
|
||||
release_line_lock(row);
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse_selection)
|
||||
SelectionOff();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void XCursesContinue(void)
|
||||
{
|
||||
if (write_display_socket_int(CURSES_CONTINUE) < 0)
|
||||
XCursesExitXCursesProcess(4, SIGKILL,
|
||||
"exiting from XCursesProcessRequestsFromCurses");
|
||||
}
|
||||
|
||||
void XCursesProcessRequestsFromCurses(XtPointer client_data, int *fid,
|
||||
XtInputId *id)
|
||||
{
|
||||
int s, idx;
|
||||
int old_row, new_row;
|
||||
int old_x, new_x;
|
||||
int pos, num_cols;
|
||||
|
||||
long length;
|
||||
|
||||
char buf[12]; /* big enough for 2 integers */
|
||||
char title[1024]; /* big enough for window title */
|
||||
|
||||
unsigned char save_atrtab[MAX_ATRTAB];
|
||||
|
||||
PDC_LOG(("%s:XCursesProcessRequestsFromCurses()\n", XCLOGMSG));
|
||||
|
||||
if (!ReceivedMapNotify)
|
||||
return;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(display_sock, &readfds);
|
||||
|
||||
if ((s = select(FD_SETSIZE, (FD_SET_CAST)&readfds, NULL,
|
||||
NULL, &socket_timeout)) < 0)
|
||||
XCursesExitXCursesProcess(2, SIGKILL, "exiting from "
|
||||
"XCursesProcessRequestsFromCurses - select failed");
|
||||
|
||||
if (s == 0) /* no requests pending - should never happen!*/
|
||||
return;
|
||||
|
||||
if (FD_ISSET(display_sock, &readfds))
|
||||
{
|
||||
/* read first integer to determine total message has
|
||||
been received */
|
||||
|
||||
PDC_LOG(("%s:XCursesProcessRequestsFromCurses() - "
|
||||
"before read_socket()\n", XCLOGMSG));
|
||||
|
||||
if (read_socket(display_sock, (char *)&num_cols, sizeof(int)) < 0)
|
||||
XCursesExitXCursesProcess(3, SIGKILL, "exiting from "
|
||||
"XCursesProcessRequestsFromCurses - first read");
|
||||
|
||||
PDC_LOG(("%s:XCursesProcessRequestsFromCurses() - "
|
||||
"after read_socket()\n", XCLOGMSG));
|
||||
|
||||
after_first_curses_request = True;
|
||||
|
||||
switch(num_cols)
|
||||
{
|
||||
case CURSES_EXIT: /* request from curses to stop */
|
||||
XC_LOG(("CURSES_EXIT received from child\n"));
|
||||
XCursesExitXCursesProcess(0, 0,
|
||||
"XCursesProcess requested to exit by child");
|
||||
break;
|
||||
|
||||
case CURSES_BELL:
|
||||
XC_LOG(("CURSES_BELL received from child\n"));
|
||||
XBell(XCURSESDISPLAY, 50);
|
||||
break;
|
||||
|
||||
/* request from curses to confirm completion of display */
|
||||
|
||||
case CURSES_REFRESH:
|
||||
XC_LOG(("CURSES_REFRESH received from child\n"));
|
||||
XCursesRefreshScreen();
|
||||
XCursesContinue();
|
||||
break;
|
||||
|
||||
case CURSES_REFRESH_SCROLLBAR:
|
||||
XCursesRefreshScrollbar();
|
||||
break;
|
||||
|
||||
case CURSES_CURSOR:
|
||||
XC_LOG(("CURSES_CURSOR received from child\n"));
|
||||
if (read_socket(display_sock, buf, sizeof(int) * 2) < 0)
|
||||
XCursesExitXCursesProcess(5, SIGKILL,
|
||||
"exiting from CURSES_CURSOR "
|
||||
"XCursesProcessRequestsFromCurses");
|
||||
|
||||
memcpy((char *)&pos, buf, sizeof(int));
|
||||
|
||||
old_row = pos & 0xFF;
|
||||
old_x = pos >> 8;
|
||||
idx = sizeof(int);
|
||||
memcpy((char *)&pos, buf + idx, sizeof(int));
|
||||
|
||||
new_row = pos & 0xFF;
|
||||
new_x = pos >> 8;
|
||||
visible_cursor = 1;
|
||||
XCursesDisplayCursor(old_row, old_x, new_row, new_x);
|
||||
break;
|
||||
|
||||
case CURSES_DISPLAY_CURSOR:
|
||||
XC_LOG(("CURSES_DISPLAY_CURSOR received from child. "
|
||||
"Vis now: "));
|
||||
XC_LOG((visible_cursor ? "1\n" : "0\n"));
|
||||
|
||||
/* If the window is not active, ignore this
|
||||
command. The cursor will stay solid. */
|
||||
|
||||
if (windowEntered)
|
||||
{
|
||||
if (visible_cursor)
|
||||
{
|
||||
/* Cursor currently ON, turn it off */
|
||||
|
||||
int save_visibility = SP->visibility;
|
||||
SP->visibility = 0;
|
||||
|
||||
XCursesDisplayCursor(SP->cursrow, SP->curscol,
|
||||
SP->cursrow, SP->curscol);
|
||||
|
||||
SP->visibility = save_visibility;
|
||||
visible_cursor = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Cursor currently OFF, turn it on */
|
||||
|
||||
XCursesDisplayCursor(SP->cursrow, SP->curscol,
|
||||
SP->cursrow, SP->curscol);
|
||||
|
||||
visible_cursor = 1;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CURSES_TITLE:
|
||||
XC_LOG(("CURSES_TITLE received from child\n"));
|
||||
|
||||
if (read_socket(display_sock, (char *)&pos, sizeof(int)) < 0)
|
||||
XCursesExitXCursesProcess(5, SIGKILL,
|
||||
"exiting from CURSES_TITLE "
|
||||
"XCursesProcessRequestsFromCurses");
|
||||
|
||||
if (read_socket(display_sock, title, pos) < 0)
|
||||
XCursesExitXCursesProcess(5, SIGKILL,
|
||||
"exiting from CURSES_TITLE "
|
||||
"XCursesProcessRequestsFromCurses");
|
||||
|
||||
XtVaSetValues(topLevel, XtNtitle, title, NULL);
|
||||
break;
|
||||
|
||||
case CURSES_RESIZE:
|
||||
after_first_curses_request = False;
|
||||
XC_LOG(("CURSES_RESIZE received from child\n"));
|
||||
|
||||
SP->lines = XCursesLINES = ((resizeXCursesWindowHeight -
|
||||
(2 * XCURSESBORDERWIDTH)) / XCursesFontHeight);
|
||||
|
||||
LINES = XCursesLINES - SP->linesrippedoff - SP->slklines;
|
||||
|
||||
SP->cols = COLS = XCursesCOLS = ((resizeXCursesWindowWidth -
|
||||
(2 * XCURSESBORDERWIDTH)) / XCursesFontWidth);
|
||||
|
||||
XCursesWindowWidth = resizeXCursesWindowWidth;
|
||||
XCursesWindowHeight = resizeXCursesWindowHeight;
|
||||
visible_cursor = 1;
|
||||
|
||||
/* Draw the border if required */
|
||||
|
||||
if (XCURSESBORDERWIDTH)
|
||||
XDrawRectangle(XCURSESDISPLAY, XCURSESWIN, border_gc,
|
||||
XCURSESBORDERWIDTH / 2, XCURSESBORDERWIDTH / 2,
|
||||
XCursesWindowWidth - XCURSESBORDERWIDTH,
|
||||
XCursesWindowHeight - XCURSESBORDERWIDTH);
|
||||
|
||||
/* Detach and drop the current shared memory segment and
|
||||
create and attach to a new segment */
|
||||
|
||||
memcpy(save_atrtab, atrtab, sizeof(save_atrtab));
|
||||
|
||||
SP->XcurscrSize = XCURSCR_SIZE;
|
||||
shmdt((char *)Xcurscr);
|
||||
shmctl(shmid_Xcurscr, IPC_RMID, 0);
|
||||
|
||||
if ((shmid_Xcurscr = shmget(shmkey_Xcurscr,
|
||||
SP->XcurscrSize + XCURSESSHMMIN, 0700 | IPC_CREAT)) < 0)
|
||||
{
|
||||
perror("Cannot allocate shared memory for curscr");
|
||||
XCursesExitXCursesProcess(4, SIGKILL,
|
||||
"exiting from XCursesProcessRequestsFromCurses");
|
||||
}
|
||||
|
||||
Xcurscr = (unsigned char*)shmat(shmid_Xcurscr, 0, 0);
|
||||
memset(Xcurscr, 0, SP->XcurscrSize);
|
||||
atrtab = (unsigned char *)(Xcurscr + XCURSCR_ATRTAB_OFF);
|
||||
memcpy(atrtab, save_atrtab, sizeof(save_atrtab));
|
||||
|
||||
XCursesContinue();
|
||||
break;
|
||||
|
||||
case CURSES_GET_SELECTION:
|
||||
XC_LOG(("CURSES_GET_SELECTION received from child\n"));
|
||||
|
||||
XCursesContinue();
|
||||
|
||||
XtGetSelectionValue(topLevel, XA_PRIMARY, XA_STRING,
|
||||
XCursesRequestorCallbackForGetSelection,
|
||||
(XtPointer)NULL, 0);
|
||||
|
||||
break;
|
||||
|
||||
case CURSES_SET_SELECTION:
|
||||
XC_LOG(("CURSES_SET_SELECTION received from child\n"));
|
||||
|
||||
if (read_socket(display_sock, (char *)&length,
|
||||
sizeof(long)) < 0)
|
||||
XCursesExitXCursesProcess(5, SIGKILL,
|
||||
"exiting from CURSES_SET_SELECTION "
|
||||
"XCursesProcessRequestsFromCurses");
|
||||
|
||||
if (length > (long)tmpsel_length)
|
||||
{
|
||||
if (tmpsel_length == 0)
|
||||
tmpsel = (chtype *)malloc((length + 1) *
|
||||
sizeof(chtype));
|
||||
else
|
||||
tmpsel = (chtype *)realloc(tmpsel, (length + 1) *
|
||||
sizeof(chtype));
|
||||
}
|
||||
|
||||
if (!tmpsel)
|
||||
{
|
||||
if (write_display_socket_int(PDC_CLIP_MEMORY_ERROR) < 0)
|
||||
XCursesExitXCursesProcess(4, SIGKILL,
|
||||
"exiting from XCursesProcessRequestsFromCurses");
|
||||
break;
|
||||
}
|
||||
|
||||
if (read_socket(display_sock, (char *)tmpsel,
|
||||
length * sizeof(chtype)) < 0)
|
||||
XCursesExitXCursesProcess(5, SIGKILL,
|
||||
"exiting from CURSES_SET_SELECTION "
|
||||
"XCursesProcessRequestsFromCurses");
|
||||
|
||||
tmpsel_length = length;
|
||||
tmpsel[length] = '\0';
|
||||
|
||||
if (XtOwnSelection(topLevel, XA_PRIMARY, CurrentTime,
|
||||
XCursesConvertProc, XCursesLoseOwnership, NULL) == False)
|
||||
{
|
||||
old_x = PDC_CLIP_ACCESS_ERROR;
|
||||
free(tmpsel);
|
||||
tmpsel = NULL;
|
||||
tmpsel_length = 0;
|
||||
}
|
||||
else
|
||||
old_x = PDC_CLIP_SUCCESS;
|
||||
|
||||
SelectionOff();
|
||||
|
||||
if (write_display_socket_int(old_x) < 0)
|
||||
XCursesExitXCursesProcess(4, SIGKILL,
|
||||
"exiting from XCursesProcessRequestsFromCurses");
|
||||
break;
|
||||
|
||||
case CURSES_CLEAR_SELECTION:
|
||||
XC_LOG(("CURSES_CLEAR_SELECTION received from child\n"));
|
||||
|
||||
XCursesContinue();
|
||||
|
||||
SelectionOff();
|
||||
break;
|
||||
|
||||
default:
|
||||
PDC_LOG(("%s:Unknown request %d\n", XCLOGMSG, num_cols));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int XCursesSetupX(int argc, char *argv[])
|
||||
{
|
||||
static char *myargv[] = {"PDCurses", NULL};
|
||||
extern bool sb_started;
|
||||
|
||||
int italic_font_valid;
|
||||
XColor pointerforecolor, pointerbackcolor;
|
||||
XrmValue rmfrom, rmto;
|
||||
int i = 0;
|
||||
int minwidth, minheight;
|
||||
|
||||
PDC_LOG(("%s:XCursesSetupX called\n", XCLOGMSG));
|
||||
|
||||
/* The following kludge is to force XtVaAppInitialize() to
|
||||
recognize the name of the program. Without it, a default
|
||||
value of "PDCurses" is used. */
|
||||
|
||||
if (!argv)
|
||||
{
|
||||
argv = myargv;
|
||||
argc = 1;
|
||||
}
|
||||
|
||||
XCursesProgramName = argv[0];
|
||||
|
||||
/* Keep open the 'write' end of the socket so the XCurses
|
||||
process can send a CURSES_EXIT to itself from within the
|
||||
signal handler */
|
||||
|
||||
exit_sock = display_sockets[0];
|
||||
display_sock = display_sockets[1];
|
||||
|
||||
close(key_sockets[0]);
|
||||
key_sock = key_sockets[1];
|
||||
|
||||
/* Trap all signals when XCurses is the child process, but only
|
||||
if they haven't already been ignored by the application. */
|
||||
|
||||
for (i = 0; i < PDC_MAX_SIGNALS; i++)
|
||||
if (XCursesSetSignal(i, XCursesSignalHandler) == SIG_IGN)
|
||||
XCursesSetSignal(i, SIG_IGN);
|
||||
|
||||
/* Start defining X Toolkit things */
|
||||
|
||||
#if XtSpecificationRelease > 4
|
||||
XtSetLanguageProc(NULL, (XtLanguageProc)NULL, NULL);
|
||||
#endif
|
||||
|
||||
/* Exit if no DISPLAY variable set */
|
||||
|
||||
if (getenv("DISPLAY") == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: no DISPLAY variable set\n");
|
||||
kill(otherpid, SIGKILL);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
/* Initialise the top level widget */
|
||||
|
||||
topLevel = XtVaAppInitialize(&app_context, XCursesClassName,
|
||||
options, XtNumber(options), &argc, argv, NULL, NULL);
|
||||
|
||||
XtVaGetApplicationResources(topLevel, &app_data, app_resources,
|
||||
XtNumber(app_resources), NULL);
|
||||
|
||||
/* Check application resource values here */
|
||||
|
||||
XCursesFontWidth = XCURSESNORMALFONTINFO->max_bounds.rbearing -
|
||||
XCURSESNORMALFONTINFO->min_bounds.lbearing;
|
||||
|
||||
XCursesFontHeight = XCURSESNORMALFONTINFO->max_bounds.ascent +
|
||||
XCURSESNORMALFONTINFO->max_bounds.descent;
|
||||
|
||||
XCursesFontAscent = XCURSESNORMALFONTINFO->max_bounds.ascent;
|
||||
XCursesFontDescent = XCURSESNORMALFONTINFO->max_bounds.descent;
|
||||
|
||||
/* Check that the italic font and normal fonts are the same size */
|
||||
/* This appears backwards */
|
||||
|
||||
italic_font_valid = XCursesFontWidth !=
|
||||
XCURSESITALICFONTINFO->max_bounds.rbearing -
|
||||
XCURSESITALICFONTINFO->min_bounds.lbearing ||
|
||||
XCursesFontHeight !=
|
||||
XCURSESITALICFONTINFO->max_bounds.ascent +
|
||||
XCURSESITALICFONTINFO->max_bounds.descent;
|
||||
|
||||
/* Calculate size of display window */
|
||||
|
||||
XCursesCOLS = XCURSESCOLS;
|
||||
XCursesLINES = XCURSESLINES;
|
||||
|
||||
XCursesWindowWidth = XCursesFontWidth * XCursesCOLS +
|
||||
2 * XCURSESBORDERWIDTH;
|
||||
|
||||
XCursesWindowHeight = XCursesFontHeight * XCursesLINES +
|
||||
2 * XCURSESBORDERWIDTH;
|
||||
|
||||
minwidth = XCursesFontWidth * 2 + XCURSESBORDERWIDTH * 2;
|
||||
minheight = XCursesFontHeight * 2 + XCURSESBORDERWIDTH * 2;
|
||||
|
||||
/* Set up the icon for the application; the default is an
|
||||
internal one for XCurses. Then set various application level
|
||||
resources. */
|
||||
|
||||
XCursesGetIcon();
|
||||
|
||||
#ifdef HAVE_XPM_H
|
||||
if (XCURSESPIXMAPFILE != NULL && strcmp(XCURSESPIXMAPFILE, "") != 0)
|
||||
XtVaSetValues(topLevel, XtNminWidth, minwidth,
|
||||
XtNminHeight, minheight,
|
||||
XtNbaseWidth, XCURSESBORDERWIDTH * 2,
|
||||
XtNbaseHeight, XCURSESBORDERWIDTH * 2,
|
||||
XtNiconPixmap, icon_pixmap,
|
||||
XtNiconMask, icon_pixmap_mask, NULL);
|
||||
else
|
||||
#endif
|
||||
XtVaSetValues(topLevel, XtNminWidth, minwidth,
|
||||
XtNminHeight, minheight,
|
||||
XtNbaseWidth, XCURSESBORDERWIDTH * 2,
|
||||
XtNbaseHeight, XCURSESBORDERWIDTH * 2,
|
||||
XtNiconPixmap, icon_bitmap, NULL);
|
||||
|
||||
/* Create a BOX widget in which to draw */
|
||||
|
||||
if (XCURSESSCROLLBARWIDTH != 0 && sb_started)
|
||||
{
|
||||
scrollBox = XtVaCreateManagedWidget(XCursesProgramName,
|
||||
scrollBoxWidgetClass, topLevel, XtNwidth,
|
||||
XCursesWindowWidth + XCURSESSCROLLBARWIDTH,
|
||||
XtNheight, XCursesWindowHeight +
|
||||
XCURSESSCROLLBARWIDTH, XtNwidthInc,
|
||||
XCursesFontWidth, XtNheightInc,
|
||||
XCursesFontHeight, NULL);
|
||||
|
||||
drawing = XtVaCreateManagedWidget(XCursesProgramName,
|
||||
boxWidgetClass, scrollBox, XtNwidth,
|
||||
XCursesWindowWidth, XtNheight,
|
||||
XCursesWindowHeight, XtNwidthInc,
|
||||
XCursesFontWidth, XtNheightInc,
|
||||
XCursesFontHeight, NULL);
|
||||
|
||||
scrollVert = XtVaCreateManagedWidget("scrollVert",
|
||||
scrollbarWidgetClass, scrollBox, XtNorientation,
|
||||
XtorientVertical, XtNheight,
|
||||
XCursesWindowHeight, XtNwidth,
|
||||
XCURSESSCROLLBARWIDTH, NULL);
|
||||
|
||||
XtAddCallback(scrollVert, XtNscrollProc,
|
||||
Scroll_up_down, drawing);
|
||||
|
||||
XtAddCallback(scrollVert, XtNjumpProc,
|
||||
Thumb_up_down, drawing);
|
||||
|
||||
scrollHoriz = XtVaCreateManagedWidget("scrollHoriz",
|
||||
scrollbarWidgetClass, scrollBox, XtNorientation,
|
||||
XtorientHorizontal, XtNwidth,
|
||||
XCursesWindowWidth, XtNheight,
|
||||
XCURSESSCROLLBARWIDTH, NULL);
|
||||
|
||||
XtAddCallback(scrollHoriz, XtNscrollProc,
|
||||
Scroll_left_right, drawing);
|
||||
|
||||
XtAddCallback(scrollHoriz, XtNjumpProc,
|
||||
Thumb_left_right, drawing);
|
||||
}
|
||||
else
|
||||
{
|
||||
drawing = XtVaCreateManagedWidget(XCursesProgramName,
|
||||
boxWidgetClass, topLevel, XtNwidth,
|
||||
XCursesWindowWidth, XtNheight,
|
||||
XCursesWindowHeight, XtNwidthInc,
|
||||
XCursesFontWidth, XtNheightInc,
|
||||
XCursesFontHeight, NULL);
|
||||
|
||||
XtVaSetValues(topLevel, XtNwidthInc, XCursesFontWidth,
|
||||
XtNheightInc, XCursesFontHeight, NULL);
|
||||
}
|
||||
|
||||
/* Process any default translations */
|
||||
|
||||
XCursesTranslations = XtParseTranslationTable(defaultTranslations);
|
||||
XtAugmentTranslations(drawing, XCursesTranslations);
|
||||
XtAppAddActions(app_context, XCursesActions, XtNumber(XCursesActions));
|
||||
|
||||
/* Process the supplied colors */
|
||||
|
||||
if (get_colors() == ERR)
|
||||
{
|
||||
kill(otherpid, SIGKILL);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
/* Determine text cursor alignment from resources */
|
||||
|
||||
if (strcmp(XCURSESTEXTCURSOR, "vertical") == 0)
|
||||
vertical_cursor = True;
|
||||
|
||||
/* Now have LINES and COLS. Set these in the shared SP so the
|
||||
curses program can find them. */
|
||||
|
||||
LINES = XCursesLINES;
|
||||
COLS = XCursesCOLS;
|
||||
|
||||
if ((shmidSP = shmget(shmkeySP, sizeof(SCREEN) + XCURSESSHMMIN,
|
||||
0700 | IPC_CREAT)) < 0)
|
||||
{
|
||||
perror("Cannot allocate shared memory for SCREEN");
|
||||
kill(otherpid, SIGKILL);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
SP = (SCREEN*)shmat(shmidSP, 0, 0);
|
||||
memset(SP, 0, sizeof(SCREEN));
|
||||
SP->XcurscrSize = XCURSCR_SIZE;
|
||||
SP->lines = XCursesLINES;
|
||||
SP->cols = XCursesCOLS;
|
||||
|
||||
PDC_LOG(("%s:SHM size for curscr %d\n", XCLOGMSG, SP->XcurscrSize));
|
||||
|
||||
if ((shmid_Xcurscr = shmget(shmkey_Xcurscr, SP->XcurscrSize +
|
||||
XCURSESSHMMIN, 0700 | IPC_CREAT)) < 0)
|
||||
{
|
||||
perror("Cannot allocate shared memory for curscr");
|
||||
kill(otherpid, SIGKILL);
|
||||
shmdt((char *)SP);
|
||||
shmctl(shmidSP, IPC_RMID, 0);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
Xcurscr = (unsigned char *)shmat(shmid_Xcurscr, 0, 0);
|
||||
memset(Xcurscr, 0, SP->XcurscrSize);
|
||||
atrtab = (unsigned char *)(Xcurscr + XCURSCR_ATRTAB_OFF);
|
||||
|
||||
PDC_LOG(("%s:shmid_Xcurscr %d shmkey_Xcurscr %d LINES %d COLS %d\n",
|
||||
XCLOGMSG, shmid_Xcurscr, shmkey_Xcurscr, LINES, COLS));
|
||||
|
||||
/* Add Event handlers to the drawing widget */
|
||||
|
||||
XtAddEventHandler(drawing, ExposureMask, False, XCursesExpose, NULL);
|
||||
XtAddEventHandler(drawing, StructureNotifyMask, False,
|
||||
XCursesStructureNotify, NULL);
|
||||
XtAddEventHandler(drawing, EnterWindowMask | LeaveWindowMask,
|
||||
False, XCursesEnterLeaveWindow, NULL);
|
||||
|
||||
XtAddEventHandler(topLevel, 0, True, XCursesNonmaskable, NULL);
|
||||
|
||||
/* Add input handler from display_sock (requests from curses
|
||||
program) */
|
||||
|
||||
XtAppAddInput(app_context, display_sock,
|
||||
(XtPointer)XtInputReadMask,
|
||||
XCursesProcessRequestsFromCurses, NULL);
|
||||
|
||||
/* If there is a cursorBlink resource, start the Timeout event */
|
||||
|
||||
if (XCURSESCURSORBLINKRATE)
|
||||
XtAppAddTimeOut(app_context, XCURSESCURSORBLINKRATE,
|
||||
XCursesCursorBlink, NULL);
|
||||
|
||||
/* Leave telling the curses process that it can start to here so
|
||||
that when the curses process makes a request, the Xcurses
|
||||
process can service the request.*/
|
||||
|
||||
write_display_socket_int(CURSES_CHILD);
|
||||
|
||||
XtRealizeWidget(topLevel);
|
||||
|
||||
/* Handle trapping of the WM_DELETE_WINDOW property */
|
||||
|
||||
wm_atom[0] = XInternAtom(XtDisplay(topLevel),
|
||||
"WM_DELETE_WINDOW", False);
|
||||
|
||||
XSetWMProtocols(XtDisplay(topLevel), XtWindow(topLevel),
|
||||
wm_atom, 1);
|
||||
|
||||
/* Create the Graphics Context for drawing. This MUST be done
|
||||
AFTER the associated widget has been realized. */
|
||||
|
||||
XC_LOG(("before get_GC\n"));
|
||||
|
||||
get_GC(XCURSESDISPLAY, XCURSESWIN, &normal_gc,
|
||||
XCURSESNORMALFONTINFO, COLOR_WHITE, COLOR_BLACK, FALSE);
|
||||
|
||||
if (italic_font_valid)
|
||||
get_GC(XCURSESDISPLAY, XCURSESWIN, &italic_gc,
|
||||
XCURSESITALICFONTINFO, COLOR_WHITE, COLOR_BLACK,
|
||||
FALSE);
|
||||
else
|
||||
get_GC(XCURSESDISPLAY, XCURSESWIN, &italic_gc,
|
||||
XCURSESNORMALFONTINFO, COLOR_WHITE, COLOR_BLACK,
|
||||
FALSE);
|
||||
|
||||
get_GC(XCURSESDISPLAY, XCURSESWIN, &block_cursor_gc,
|
||||
XCURSESNORMALFONTINFO, COLOR_BLACK, COLOR_CURSOR, FALSE);
|
||||
|
||||
get_GC(XCURSESDISPLAY, XCURSESWIN, &rect_cursor_gc,
|
||||
XCURSESNORMALFONTINFO, COLOR_CURSOR, COLOR_BLACK, FALSE);
|
||||
|
||||
get_GC(XCURSESDISPLAY, XCURSESWIN, &border_gc,
|
||||
XCURSESNORMALFONTINFO, COLOR_BORDER, COLOR_BLACK, FALSE);
|
||||
|
||||
XSetLineAttributes(XCURSESDISPLAY, rect_cursor_gc, 2, LineSolid,
|
||||
CapButt, JoinMiter);
|
||||
|
||||
XSetLineAttributes(XCURSESDISPLAY, border_gc,
|
||||
XCURSESBORDERWIDTH, LineSolid, CapButt, JoinMiter);
|
||||
|
||||
/* Set the cursor for the application */
|
||||
|
||||
XDefineCursor(XCURSESDISPLAY, XCURSESWIN, XCURSESPOINTER);
|
||||
rmfrom.size = sizeof(Pixel);
|
||||
rmto.size = sizeof(XColor);
|
||||
|
||||
#if XtSpecificationRelease > 4
|
||||
rmto.addr = (XPointer)&pointerforecolor;
|
||||
rmfrom.addr = (XPointer)&(XCURSESPOINTERFORECOLOR);
|
||||
XtConvertAndStore(drawing, XtRPixel, &rmfrom, XtRColor, &rmto);
|
||||
#else
|
||||
rmto.addr = (char *)&pointerforecolor;
|
||||
rmfrom.addr = (char *)&(XCURSESPOINTERFORECOLOR);
|
||||
XtConvert(drawing, XtRPixel, &rmfrom, XtRColor, &rmto);
|
||||
#endif
|
||||
|
||||
rmfrom.size = sizeof(Pixel);
|
||||
rmto.size = sizeof(XColor);
|
||||
|
||||
#if XtSpecificationRelease > 4
|
||||
rmfrom.addr = (XPointer)&(XCURSESPOINTERBACKCOLOR);
|
||||
rmto.addr = (XPointer)&pointerbackcolor;
|
||||
XtConvertAndStore(drawing, XtRPixel, &rmfrom, XtRColor, &rmto);
|
||||
#else
|
||||
rmfrom.addr = (char *)&(XCURSESPOINTERBACKCOLOR);
|
||||
rmto.addr = (char *)&pointerbackcolor;
|
||||
XtConvert(drawing, XtRPixel, &rmfrom, XtRColor, &rmto);
|
||||
#endif
|
||||
|
||||
XRecolorCursor(XCURSESDISPLAY, XCURSESPOINTER,
|
||||
&pointerforecolor, &pointerbackcolor);
|
||||
|
||||
/* Convert the supplied compose key to a Keysym */
|
||||
|
||||
compose_key = XStringToKeysym(XCURSESCOMPOSEKEY);
|
||||
|
||||
if (compose_key && IsModifierKey(compose_key))
|
||||
{
|
||||
int i, j;
|
||||
KeyCode *kcp;
|
||||
XModifierKeymap *map;
|
||||
KeyCode compose_keycode =
|
||||
XKeysymToKeycode(XCURSESDISPLAY, compose_key);
|
||||
|
||||
map = XGetModifierMapping(XCURSESDISPLAY);
|
||||
kcp = map->modifiermap;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
for (j = 0; j < map->max_keypermod; j++, kcp++)
|
||||
{
|
||||
if (!*kcp)
|
||||
continue;
|
||||
|
||||
if (compose_keycode == *kcp)
|
||||
{
|
||||
compose_mask = state_mask[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (compose_mask)
|
||||
break;
|
||||
}
|
||||
|
||||
XFreeModifiermap(map);
|
||||
}
|
||||
|
||||
#ifdef FOREIGN
|
||||
sleep(20);
|
||||
|
||||
if ((Xim = XOpenIM(XCURSESDISPLAY,NULL,NULL,NULL)) == NULL)
|
||||
{
|
||||
perror("Cannot open Input Method");
|
||||
kill(otherpid, SIGKILL);
|
||||
shmdt((char *)SP);
|
||||
shmdt((char *)Xcurscr);
|
||||
shmctl(shmidSP, IPC_RMID, 0);
|
||||
shmctl(shmid_Xcurscr, IPC_RMID, 0);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
XGetIMValues(Xim,XNQueryInputStyle, &im_supported_styles, NULL);
|
||||
my_style = XIMPreeditNone | XIMStatusNone;
|
||||
|
||||
if ((Xic = XCreateIC(Xim, XNInputStyle, my_style, NULL)) == NULL)
|
||||
{
|
||||
perror("ERROR: Cannot create input context");
|
||||
kill(otherpid, SIGKILL);
|
||||
shmdt((char *)SP);
|
||||
shmdt((char *)Xcurscr);
|
||||
shmctl(shmidSP, IPC_RMID, 0);
|
||||
shmctl(shmid_Xcurscr, IPC_RMID, 0);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
XFree(im_supported_styles);
|
||||
XGetICValues(Xic, XNFilterEvents, &im_event_mask, NULL);
|
||||
XtAddEventHandler(drawing, im_event_mask, False, NULL, NULL);
|
||||
XSetICFocus(Xic);
|
||||
#endif
|
||||
|
||||
/* Wait for events */
|
||||
|
||||
XtAppMainLoop(app_context);
|
||||
return OK; /* won't get here */
|
||||
}
|
||||
|
||||
RETSIGTYPE XCursesSignalHandler(int signo)
|
||||
{
|
||||
int flag = CURSES_EXIT;
|
||||
|
||||
PDC_LOG(("%s:XCursesSignalHandler() - called: %d\n", XCLOGMSG, signo));
|
||||
|
||||
/* Patch by: Georg Fuchs */
|
||||
|
||||
XCursesSetSignal(signo, XCursesSignalHandler);
|
||||
|
||||
#ifdef SIGTSTP
|
||||
if (signo == SIGTSTP)
|
||||
{
|
||||
pause();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef SIGCONT
|
||||
if (signo == SIGCONT)
|
||||
return;
|
||||
#endif
|
||||
#ifdef SIGCLD
|
||||
if (signo == SIGCLD)
|
||||
return;
|
||||
#endif
|
||||
#ifdef SIGTTIN
|
||||
if (signo == SIGTTIN)
|
||||
return;
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
if (signo == SIGWINCH)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* End of patch by: Georg Fuchs */
|
||||
|
||||
XCursesSetSignal(signo, SIG_IGN);
|
||||
|
||||
/* Send a CURSES_EXIT to myself */
|
||||
|
||||
if (write_socket(exit_sock, (char *)&flag, sizeof(int)) < 0)
|
||||
XCursesExitXCursesProcess(7, signo,
|
||||
"exiting from XCursesSignalHandler");
|
||||
}
|
||||
|
||||
void XCursesRequestorCallbackForGetSelection(Widget w, XtPointer data,
|
||||
Atom *selection, Atom *type,
|
||||
XtPointer value,
|
||||
unsigned long *length, int *format)
|
||||
{
|
||||
PDC_LOG(("%s:XCursesRequestorCallbackForSelection() - called\n",
|
||||
XCLOGMSG));
|
||||
|
||||
if ((value == NULL) && (*length == 0))
|
||||
{
|
||||
if (write_display_socket_int(PDC_CLIP_EMPTY) >= 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Here all is OK, send PDC_CLIP_SUCCESS, then length, then
|
||||
contents */
|
||||
|
||||
if (write_display_socket_int(PDC_CLIP_SUCCESS) >= 0)
|
||||
if (write_display_socket_int((int)(*length)) >= 0)
|
||||
if (write_socket(display_sock, (char *)value, *length) >= 0)
|
||||
return;
|
||||
}
|
||||
|
||||
XCursesExitXCursesProcess(4, SIGKILL,
|
||||
"exiting from XCursesRequestorCallbackForGetSelection");
|
||||
}
|
||||
|
||||
void XCursesStructureNotify(Widget w, XtPointer client_data, XEvent *event,
|
||||
Boolean *continue_to_dispatch)
|
||||
{
|
||||
PDC_LOG(("%s:XCursesStructureNotify called\n", XCLOGMSG));
|
||||
|
||||
switch(event->type)
|
||||
{
|
||||
case ConfigureNotify:
|
||||
XC_LOG(("ConfigureNotify received\n"));
|
||||
|
||||
/* Window has been resized, change width and height to
|
||||
send to place_text and place_graphics in next Expose.
|
||||
Also will need to kill (SIGWINCH) curses process if
|
||||
screen size changes. */
|
||||
|
||||
resizeXCursesWindowWidth = (event->xconfigure.width);
|
||||
resizeXCursesWindowHeight = (event->xconfigure.height);
|
||||
|
||||
after_first_curses_request = False;
|
||||
|
||||
#ifdef SIGWINCH
|
||||
SP->resized = 1;
|
||||
|
||||
kill(otherpid, SIGWINCH);
|
||||
#endif
|
||||
XCursesSendKeyToCurses((unsigned long)KEY_RESIZE, NULL);
|
||||
break;
|
||||
|
||||
case MapNotify:
|
||||
XC_LOG(("MapNotify received\n"));
|
||||
|
||||
ReceivedMapNotify = 1;
|
||||
|
||||
/* Draw the window border */
|
||||
|
||||
if (XCURSESBORDERWIDTH)
|
||||
XDrawRectangle(XCURSESDISPLAY, XCURSESWIN,
|
||||
border_gc, XCURSESBORDERWIDTH / 2,
|
||||
XCURSESBORDERWIDTH / 2,
|
||||
XCursesWindowWidth - XCURSESBORDERWIDTH,
|
||||
XCursesWindowHeight - XCURSESBORDERWIDTH);
|
||||
break;
|
||||
|
||||
default:
|
||||
PDC_LOG(("%s:XCursesStructureNotify - unknown event %d\n",
|
||||
XCLOGMSG, event->type));
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/************************************************************************
|
||||
* This file is part of PDCurses. PDCurses is public domain software; *
|
||||
* you may use it for any purpose. This software is provided AS IS with *
|
||||
* NO WARRANTY whatsoever. *
|
||||
* *
|
||||
* If you use PDCurses in an application, an acknowledgement would be *
|
||||
* appreciated, but is not mandatory. If you make corrections or *
|
||||
* enhancements to PDCurses, please forward them to the current *
|
||||
* maintainer for the benefit of other users. *
|
||||
* *
|
||||
* No distribution of modified PDCurses code may be made under the name *
|
||||
* "PDCurses", except by the current maintainer. (Although PDCurses is *
|
||||
* public domain, the name is a trademark.) *
|
||||
* *
|
||||
* See the file maintain.er for details of the current maintainer. *
|
||||
************************************************************************/
|
||||
|
||||
#include "pdcx11.h"
|
||||
|
||||
RCSID("$Id: x11common.c,v 1.17 2006/07/21 04:07:05 wmcbrine Exp $");
|
||||
|
||||
/* Variables specific to process port */
|
||||
|
||||
unsigned char *Xcurscr;
|
||||
|
||||
int XCursesProcess = 1;
|
||||
int shmidSP;
|
||||
int shmid_Xcurscr;
|
||||
int shmkeySP;
|
||||
int shmkey_Xcurscr;
|
||||
int otherpid;
|
||||
int XCursesLINES = 24;
|
||||
int XCursesCOLS = 80;
|
||||
int display_sock;
|
||||
int key_sock;
|
||||
int display_sockets[2];
|
||||
int key_sockets[2];
|
||||
int exit_sock;
|
||||
|
||||
fd_set readfds;
|
||||
fd_set writefds;
|
||||
|
||||
struct timeval socket_timeout;
|
||||
|
||||
static void dummy_function(void)
|
||||
{
|
||||
}
|
||||
|
||||
void get_line_lock(int row)
|
||||
{
|
||||
/* loop until we can write to the line -- Patch by:
|
||||
Georg Fuchs, georg.fuchs@rz.uni-regensburg.de */
|
||||
|
||||
while (*(Xcurscr + XCURSCR_FLAG_OFF + row))
|
||||
dummy_function();
|
||||
|
||||
*(Xcurscr + XCURSCR_FLAG_OFF + row) = 1;
|
||||
}
|
||||
|
||||
void release_line_lock(int row)
|
||||
{
|
||||
*(Xcurscr + XCURSCR_FLAG_OFF + row) = 0;
|
||||
}
|
||||
|
||||
int write_socket(int sock_num, const char *buf, int len)
|
||||
{
|
||||
int start = 0, rc;
|
||||
|
||||
PDC_LOG(("%s:write_socket called: sock_num %d len %d\n",
|
||||
XCLOGMSG, sock_num, len));
|
||||
|
||||
#ifdef MOUSE_DEBUG
|
||||
if (sock_num == key_sock)
|
||||
printf("%s:write_socket(key) len: %d\n", XCLOGMSG, len);
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
rc = write(sock_num, buf + start, len);
|
||||
|
||||
if (rc < 0 || rc == len)
|
||||
return rc;
|
||||
|
||||
len -= rc;
|
||||
start = rc;
|
||||
}
|
||||
}
|
||||
|
||||
int read_socket(int sock_num, char *buf, int len)
|
||||
{
|
||||
int start = 0, length = len, rc;
|
||||
|
||||
PDC_LOG(("%s:read_socket called: sock_num %d len %d\n",
|
||||
XCLOGMSG, sock_num, len));
|
||||
|
||||
while (1)
|
||||
{
|
||||
rc = read(sock_num, buf + start, length);
|
||||
|
||||
#ifdef MOUSE_DEBUG
|
||||
if (sock_num == key_sock)
|
||||
printf("%s:read_socket(key) rc %d errno %d resized: %d\n",
|
||||
XCLOGMSG, rc, errno, SP->resized);
|
||||
#endif
|
||||
if (rc < 0 && sock_num == key_sock && errno == EINTR
|
||||
&& SP->resized != FALSE)
|
||||
{
|
||||
MOUSE_LOG(("%s:continuing\n", XCLOGMSG));
|
||||
|
||||
rc = 0;
|
||||
|
||||
if (SP->resized > 1)
|
||||
SP->resized = TRUE;
|
||||
else
|
||||
SP->resized = FALSE;
|
||||
|
||||
memcpy(buf, (char *)&rc, sizeof(int));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rc <= 0 || rc == length)
|
||||
return rc;
|
||||
|
||||
length -= rc;
|
||||
start = rc;
|
||||
}
|
||||
}
|
||||
|
||||
int write_display_socket_int(int x)
|
||||
{
|
||||
return write_socket(display_sock, (char *)&x, sizeof(int));
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
/************************************************************************
|
||||
* This file is part of PDCurses. PDCurses is public domain software; *
|
||||
* you may use it for any purpose. This software is provided AS IS with *
|
||||
* NO WARRANTY whatsoever. *
|
||||
* *
|
||||
* If you use PDCurses in an application, an acknowledgement would be *
|
||||
* appreciated, but is not mandatory. If you make corrections or *
|
||||
* enhancements to PDCurses, please forward them to the current *
|
||||
* maintainer for the benefit of other users. *
|
||||
* *
|
||||
* No distribution of modified PDCurses code may be made under the name *
|
||||
* "PDCurses", except by the current maintainer. (Although PDCurses is *
|
||||
* public domain, the name is a trademark.) *
|
||||
* *
|
||||
* See the file maintain.er for details of the current maintainer. *
|
||||
************************************************************************/
|
||||
|
||||
/* This file contains functions that are called by the "curses" process;
|
||||
i.e., the parent process. */
|
||||
|
||||
#include "pdcx11.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
RCSID("$Id: x11curses.c,v 1.38 2006/07/21 03:23:50 wmcbrine Exp $");
|
||||
|
||||
int XCursesInstruct(int flag)
|
||||
{
|
||||
PDC_LOG(("%s:XCursesInstruct() - called flag %d\n", XCLOGMSG, flag));
|
||||
|
||||
/* Send a request to X */
|
||||
|
||||
if (write_display_socket_int(flag) < 0)
|
||||
XCursesExitCursesProcess(4, "exiting from XCursesInstruct");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int XCursesInstructAndWait(int flag)
|
||||
{
|
||||
int result;
|
||||
|
||||
PDC_LOG(("%s:XCursesInstructAndWait() - called\n", XCLOGMSG));
|
||||
|
||||
/* tell X we want to do something */
|
||||
|
||||
XCursesInstruct(flag);
|
||||
|
||||
/* wait for X to say the refresh has occurred*/
|
||||
|
||||
if (read_socket(display_sock, (char *)&result, sizeof(int)) < 0)
|
||||
XCursesExitCursesProcess(5,
|
||||
"exiting from XCursesInstructAndWait");
|
||||
|
||||
if (result != CURSES_CONTINUE)
|
||||
XCursesExitCursesProcess(6, "exiting from "
|
||||
"XCursesInstructAndWait - synchronization error");
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int XCursesSetupCurses(void)
|
||||
{
|
||||
int wait_value;
|
||||
|
||||
PDC_LOG(("%s:XCursesSetupCurses called\n", XCLOGMSG));
|
||||
|
||||
close(display_sockets[1]);
|
||||
close(key_sockets[1]);
|
||||
|
||||
display_sock = display_sockets[0];
|
||||
key_sock = key_sockets[0];
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
|
||||
read_socket(display_sock, (char *)&wait_value, sizeof(int));
|
||||
|
||||
if (wait_value != CURSES_CHILD)
|
||||
return ERR;
|
||||
|
||||
/* Set LINES and COLS now so that the size of the shared memory
|
||||
segment can be allocated */
|
||||
|
||||
if ((shmidSP = shmget(shmkeySP, sizeof(SCREEN) + XCURSESSHMMIN,
|
||||
0700)) < 0)
|
||||
{
|
||||
perror("Cannot allocate shared memory for SCREEN");
|
||||
kill(otherpid, SIGKILL);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
SP = (SCREEN*)shmat(shmidSP, 0, 0);
|
||||
|
||||
XCursesLINES = SP->lines;
|
||||
LINES = XCursesLINES - SP->linesrippedoff - SP->slklines;
|
||||
XCursesCOLS = COLS = SP->cols;
|
||||
|
||||
if ((shmid_Xcurscr = shmget(shmkey_Xcurscr,
|
||||
SP->XcurscrSize + XCURSESSHMMIN, 0700)) < 0)
|
||||
{
|
||||
perror("Cannot allocate shared memory for curscr");
|
||||
kill(otherpid, SIGKILL);
|
||||
return ERR;
|
||||
}
|
||||
|
||||
PDC_LOG(("%s:shmid_Xcurscr %d shmkey_Xcurscr %d LINES %d COLS %d\n",
|
||||
XCLOGMSG, shmid_Xcurscr, shmkey_Xcurscr, LINES, COLS));
|
||||
|
||||
Xcurscr = (unsigned char *)shmat(shmid_Xcurscr, 0, 0);
|
||||
atrtab = (unsigned char *)(Xcurscr + XCURSCR_ATRTAB_OFF);
|
||||
|
||||
XC_LOG(("cursesprocess exiting from Xinitscr\n"));
|
||||
|
||||
/* Always trap SIGWINCH if the C library supports SIGWINCH */
|
||||
|
||||
XCursesSetSignal(SIGWINCH, XCursesSigwinchHandler);
|
||||
|
||||
atexit(XCursesExit);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int XCursesInitscr(int argc, char *argv[])
|
||||
{
|
||||
int pid, rc;
|
||||
|
||||
PDC_LOG(("%s:XCursesInitscr() - called\n", XCLOGMSG));
|
||||
|
||||
#if defined FOREIGN
|
||||
if (setlocale(LC_ALL, "") == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: cannot set locale\n");
|
||||
return ERR;
|
||||
}
|
||||
|
||||
if (!XSupportsLocale())
|
||||
{
|
||||
fprintf(stderr, "ERROR: X does not support locale\n");
|
||||
return ERR;
|
||||
}
|
||||
|
||||
if (XSetLocaleModifiers("") == NULL)
|
||||
fprintf(stderr, "WARNING: Cannot set locale modifiers\n");
|
||||
#endif
|
||||
shmkeySP = getpid();
|
||||
memset(&socket_timeout, '\0', sizeof(socket_timeout));
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, display_sockets) < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: cannot create display socketpair\n");
|
||||
return ERR;
|
||||
}
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, key_sockets) < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: cannot create key socketpair\n");
|
||||
return ERR;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
|
||||
switch(pid)
|
||||
{
|
||||
case -1:
|
||||
fprintf(stderr, "ERROR: cannot fork()\n");
|
||||
return ERR;
|
||||
break;
|
||||
|
||||
case 0: /* child */
|
||||
shmkey_Xcurscr = getpid();
|
||||
#ifdef XISPARENT
|
||||
XCursesProcess = 0;
|
||||
rc = XCursesSetupCurses();
|
||||
#else
|
||||
XCursesProcess = 1;
|
||||
otherpid = getppid();
|
||||
rc = XCursesSetupX(argc, argv);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default: /* parent */
|
||||
shmkey_Xcurscr = pid;
|
||||
#ifdef XISPARENT
|
||||
XCursesProcess = 1;
|
||||
otherpid = pid;
|
||||
rc = XCursesSetupX(argc, argv);
|
||||
#else
|
||||
XCursesProcess = 0;
|
||||
rc = XCursesSetupCurses();
|
||||
#endif
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void XCursesCleanupCursesProcess(int rc)
|
||||
{
|
||||
PDC_LOG(("%s:XCursesCleanupCursesProcess() - called: %d\n",
|
||||
XCLOGMSG, rc));
|
||||
|
||||
shutdown(display_sock, 2);
|
||||
close(display_sock);
|
||||
|
||||
shutdown(key_sock, 2);
|
||||
close(key_sock);
|
||||
|
||||
shmdt((char *)SP);
|
||||
shmdt((char *)Xcurscr);
|
||||
|
||||
if (rc)
|
||||
_exit(rc);
|
||||
}
|
||||
|
||||
void XCursesExitCursesProcess(int rc, char *msg)
|
||||
{
|
||||
PDC_LOG(("%s:XCursesExitCursesProcess() - called: %d %s\n",
|
||||
XCLOGMSG, rc, msg));
|
||||
|
||||
endwin();
|
||||
XCursesCleanupCursesProcess(rc);
|
||||
}
|
||||
|
||||
void XCursesExit(void)
|
||||
{
|
||||
static bool called = FALSE;
|
||||
|
||||
PDC_LOG(("%s:XCursesExit() - called\n", XCLOGMSG));
|
||||
|
||||
if (FALSE == called)
|
||||
{
|
||||
XCursesInstruct(CURSES_EXIT);
|
||||
XCursesCleanupCursesProcess(0);
|
||||
|
||||
called = TRUE;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user