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:
William McBrine
2006-07-21 15:28:18 +00:00
parent 136029b9c9
commit 82a1145ecd
8 changed files with 4004 additions and 4077 deletions

View File

@@ -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 \

View File

@@ -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

View File

@@ -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)

File diff suppressed because it is too large Load Diff

View File

@@ -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));
}
}

View File

@@ -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));
}

View File

@@ -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;
}
}

3742
x11/x11.c Normal file

File diff suppressed because it is too large Load Diff