drapeau@sioux.Stanford.EDU (George Drapeau) (09/08/90)
Here is my system:
Sparcstation 1 running SunOS 4.1, OpenWindows 2.0 FCS.
In $OPENWINHOME/share/src/sun/xview/examples/seln_svc, there is a
sample program called "text_seln.c". I believe it is used in the
O'Reilly book on XView, on pages 339-342.
If I compile the program with Sun CC, it works just fine. However, if
I compile with GCC, it crashes in the function "seln_holder_same_client".
My question is: why? What am I doing wrong?
Included is the Makefile and the source code to reproduce the error.
Any help whatsoever would be greatly appreciated.
George
-------------------------- cut here --------------------------
CC = gcc -DNOSTDHDRS -fstrength-reduce -fpcc-struct-return -fwritable-strings -traditional
INCLUDE = -I${OPENWINHOME}/include
CFLAGS = ${INCLUDE} -g
XVIEW_LIBS = -L${OPENWINHOME}/lib \
-lxview -lolgx -lX11
CFILES = text_seln.c
OBJS = text_seln
all: ${OBJS}
${OBJS}: $$@.c $$@.o
${CC} ${CFLAGS} ${LDFLAGS} -o $@ $@.o ${XVIEW_LIBS}
clean:
rm -f core ${OBJS} *.o
-------------------------- cut here --------------------------
/*
* seln.c -- print the primary selection from the server. If the
* selection is in a text subwindow, also print information about
* the line number(s) the selection spans and the indexes of
* the bytes within the textsw's buffer.
*/
#include <stdio.h>
#include <xview/xview.h>
#include <xview/textsw.h>
#include <xview/panel.h>
#include <xview/server.h>
#include <xview/seln.h>
Xv_Server server;
Textsw textsw;
char *get_selection();
main(argc, argv)
char *argv[];
{
Frame frame;
Panel panel;
void exit();
int print_seln();
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(NULL, FRAME,
FRAME_LABEL, argv[0],
NULL);
panel = (Panel)xv_create(frame, PANEL,
WIN_WIDTH, WIN_EXTEND_TO_EDGE,
NULL);
(void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, exit,
NULL);
(void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Get Selection",
PANEL_NOTIFY_PROC, print_seln,
NULL);
window_fit(panel);
textsw = (Textsw)xv_create(frame, TEXTSW,
WIN_X, 0,
WIN_BELOW, panel,
WIN_ROWS, 10,
WIN_COLUMNS, 80,
TEXTSW_FILE_CONTENTS, "/etc/passwd",
NULL);
window_fit(frame);
server = (Xv_Server)xv_get(xv_get(frame, XV_SCREEN), SCREEN_SERVER);
xv_main_loop(frame);
}
int
print_seln()
{
char *text = get_selection();
if (text)
printf("---selection---\n%s\n---end seln---\n", text);
return XV_OK;
}
/*
* Get the selection using selection_ask(). Note that if the
* selection is bigger than about 2K, the whole selection will
* not be gotten with one call, thus this method of getting the
* selection may not be sufficient.
*/
char *
get_selection()
{
long sel_lin_num, lines_selected;
Textsw_index first, last;
Seln_holder holder;
Seln_result result;
int len;
Seln_request *response;
static char selection_buf[BUFSIZ];
register char *ptr;
/* get the holder of the primary selection */
holder = selection_inquire(server, SELN_PRIMARY);
/* If the selection occurs in the text subwindow, print lots of
* info about the selection.
*/
if (seln_holder_same_client(&holder, textsw)) {
/* ask for information from the selection service */
response = selection_ask(server, &holder,
/* get index of the first and last chars in the textsw */
SELN_REQ_FIRST, NULL,
SELN_REQ_LAST, NULL,
/* get the actual selection bytes */
SELN_REQ_CONTENTS_ASCII, NULL,
/* Now fool the textsw to think entire lines are selected */
SELN_REQ_FAKE_LEVEL, SELN_LEVEL_LINE,
/* Get the line numbers of beginning and ending of the
* selection */
SELN_REQ_FIRST_UNIT, NULL,
SELN_REQ_LAST_UNIT, NULL,
NULL);
/* set the ptr to beginning of data -- SELN_REQ_FIRST */
ptr = response->data;
/* "first" is data succeeding SELN_REQ_FIRST -- skip attr */
first = *(Textsw_index *)(ptr += sizeof(SELN_REQ_FIRST));
ptr += sizeof(Textsw_index); /* skip over value of "first" */
/* "last" is data succeeding SELN_REQ_LAST -- skip attr */
last = *(Textsw_index *)(ptr += sizeof(SELN_REQ_LAST));
ptr += sizeof(Textsw_index); /* skip over value of "last" */
/* advance pointer past SELN_REQ_CONTENTS_ASCII */
ptr += sizeof(SELN_REQ_CONTENTS_ASCII);
len = strlen(ptr); /* length of string in response */
(void) strcpy(selection_buf, ptr);
/*
* advance pointer past length of string. If the string length
* isn't aligned to a 4-byte boundary, add the difference in
* bytes -- then advance pointer passed "value".
*/
if (len % 4)
len = len + (4 - (len % 4));
ptr += len + sizeof(Seln_attribute); /* skip over "value" */
/* advance pointer past SELN_REQ_FAKE_LEVEL, SELN_LEVEL_LINE */
ptr += sizeof(SELN_REQ_FAKE_LEVEL) + sizeof(SELN_LEVEL_LINE);
sel_lin_num = *(long *)(ptr += sizeof(SELN_REQ_FIRST_UNIT));
ptr += sizeof(long);
lines_selected = *(long *)(ptr += sizeof(SELN_REQ_LAST_UNIT));
ptr += sizeof(long);
/* hack to workaround bug with SELN_REQ_LAST_UNIT always
* returning -1. Count the lines explicitly in the selection.
*/
if (lines_selected < 0) {
register char *p;
lines_selected++;
for (p = selection_buf; *p; p++)
if (*p == '\n')
lines_selected++;
}
printf("index in textsw: %d-%d, line number(s) = %d-%d\n",
first+1, last+1, sel_lin_num+1,
sel_lin_num + lines_selected + 1);
} else {
/* the selection does not lie in our text subwindow */
response = selection_ask(server, &holder,
SELN_REQ_CONTENTS_ASCII, NULL,
NULL);
if (response->status != SELN_SUCCESS) {
printf("selection_ask() returns %d\n", response->status);
return NULL;
}
(void) strcpy(selection_buf,
response->data + sizeof(SELN_REQ_CONTENTS_ASCII));
}
return selection_buf;
}
--
______________________________________________________________________________
George D. Drapeau Internet: drapeau@jessica.stanford.edu
Academic Information Resources
Stanford University