Sophie

Sophie

distrib > Mandriva > 8.2 > i586 > media > contrib > by-pkgid > 6eba807cde0901ccac25e04745f685eb > files > 240

xview-devel-examples-3.2p1.4-8mdk.i586.rpm

/*
 * seln.c -- print the primary selection from the server.  If the
 * selection is in a text subwindow, then print information about
 * the line number(s) the selection spans and the indexes of the
 * bytes within the textsw's text stream.  This simple program
 * may not be sufficient for general usage -- see comments in
 * get_selection() comments below.
 */
#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        print_seln(), exit();

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

void
print_seln()
{
    char *text = get_selection();

    if (text)
        printf("---selection---\n%s\n---end seln---\n", text);
}

/*
 * 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       *request;
    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, (char *)textsw)) {
        /* ask for information from the selection service */
        request = selection_ask(server, &holder,
            /* get the index of the first and last chars in seln */
            SELN_REQ_FIRST,             NULL,
            SELN_REQ_LAST,              NULL,
            /* get the actual selection bytes */
            SELN_REQ_CONTENTS_ASCII,    NULL,
            /* fool the textsw to think entire lines are selected */
            SELN_REQ_FAKE_LEVEL,        SELN_LEVEL_LINE,
            /* line numbers of beginning and ending of the seln */
            SELN_REQ_FIRST_UNIT,        NULL,
            SELN_REQ_LAST_UNIT,         NULL,
            NULL);
        /* set the ptr to beginning of data -- SELN_REQ_FIRST */
        ptr = request->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 request */
        (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 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.  We have to count the line numbers ourselves.
         */
        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 is not in the text subwindow */
        request = selection_ask(server, &holder,
            SELN_REQ_CONTENTS_ASCII, NULL,
            NULL);
        if (request->status != SELN_SUCCESS) {
            printf("selection_ask() returns %d\n", request->status);
            return "";
        }
        (void) strcpy(selection_buf,
            request->data + sizeof(SELN_REQ_CONTENTS_ASCII));
    }
    return selection_buf;
}