/* * Copyright (C) 1997 and 1998 WIDE Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Id: plist.c,v 1.23 2003/05/19 07:29:45 nishida Exp $ */ #include "mgp.h" #define PL_X_MARGIN 10 static Window pl_titlewin = None; static Window pg_win = None; static Pixmap pg_tmp; static int pg_lastpage = -1; static struct ctrl *pg_lastcp = NULL; static int draw_kstring __P((Drawable, char *, int, int)); /* * Display Page List at the bottom of the window */ void pl_on(state) struct render_state *state; { XSetWindowAttributes wattr; int i, ny, pl_x; u_int pl_nx, pl_ny, pl_y; if (pl_titlewin || !plfs) return; /* number of pages in x-axis */ pl_nx = (window_width - 2 * PL_X_MARGIN) / pl_fw / 3; /* number of pages in y-axis */ pl_ny = maxpage / pl_nx + 1; /* page list coordinate */ pl_x = PL_X_MARGIN; /* keep 5 for timebar*/ pl_y = window_height - (pl_ny + 1) * pl_fh - (t_fin ? 5 : 0); pl_titlewin = XCreateSimpleWindow(display, window, 0, pl_y - pl_fh, window_width, pl_fh, 0, BlackPixel(display, 0), back_color[caching]); XSelectInput(display, pl_titlewin, StructureNotifyMask); for (i = 1; i <= maxpage; i++) { ny = (i - 1) / pl_nx; plwin[i] = XCreateSimpleWindow(display, window, pl_x + 3 * ((i - 1) % pl_nx) * pl_fw, pl_y + pl_fh * ny, 3 * pl_fw, pl_fh, 0, BlackPixel(display, 0), WhitePixel(display, 0)); wattr.do_not_propagate_mask = ButtonPressMask|ButtonReleaseMask; XChangeWindowAttributes(display, plwin[i], CWDontPropagate, &wattr); XSelectInput(display, plwin[i], ButtonPressMask|EnterWindowMask| LeaveWindowMask|StructureNotifyMask); } XMapSubwindows(display, window); for (i = 1; i <= maxpage; i++) pl_pdraw(state, i, gc_pl); } /* * Turn off the page list */ void pl_off(state) struct render_state *state; { int i; if (!pl_titlewin) return; XUnmapSubwindows(display, window); XDestroyWindow(display, pl_titlewin); pl_titlewin = None; for (i = 1; i <= maxpage; i++) { XDestroyWindow(display, plwin[i]); plwin[i] = None; } XMapSubwindows(display, window); XFlush(display); } /* * Draw page numbers in each small window * Enbold the current page */ void pl_pdraw(state, i, gc) struct render_state *state; int i; GC gc; { char buf[10]; if (!pl_titlewin) return; sprintf(buf, "%02d", i % 100); XDrawImageString(display, plwin[i], gc, (int)(pl_fw / 2), (int)(pl_fh / 1.2), buf, 2); if (i == state->page) XDrawString(display, plwin[i], gc, (int)(pl_fw / 2) + 1, (int)(pl_fh / 1.2), buf, 2); } /* * Show the title of the page when the mouse enters a window. * Turn it off if the page number is zero. */ void pl_title(page) u_int page; { char buf[BUFSIZ]; if (!pl_titlewin) return; XClearArea(display, pl_titlewin, 0, 0, window_width, pl_fh, 0); if (page == 0) return; sprintf(buf, "page %d: %s", page, page_title(page)); XSetForeground(display, gc_pta, ctrl_color[caching]); XSetForeground(display, gc_ptk, ctrl_color[caching]); XSetBackground(display, gc_pta, back_color[caching]); XSetBackground(display, gc_ptk, back_color[caching]); draw_kstring(pl_titlewin, buf, PL_X_MARGIN, pl_fh - plfs->max_bounds.descent); } /* * Returns a pointer to title of specified page. */ char * page_title(page) int page; { int l; char *p; struct ctrl *cp; p = ""; for (l = 0; l <= page_attribute[page].pg_linenum; l++) { cp = page_control[page][l]; while (cp && cp->ct_op != CTL_TEXT) cp = cp->ct_next; if (!cp) continue; if (cp->ctc_value && *cp->ctc_value) { p = cp->ctc_value; break; } } while (*p && isspace(*p)) p++; return p; } void pg_on() { if (pg_win) return; /* 5 for timebar*/ pg_win = XCreateSimpleWindow(display, window, 0, window_height - pl_fh - (t_fin ? 5 : 0), window_width, pl_fh, 0, BlackPixel(display, screen), back_color[caching]); XSelectInput(display, pg_win, StructureNotifyMask); XMapSubwindows(display, window); pg_tmp = XCreatePixmap(display, pg_win, window_width, pl_fh, depth); pg_lastpage = -1; pg_lastcp = NULL; } void pg_clean() { XClearArea(display, pg_win, 0, 0, window_width, pl_fh, 0); pg_lastpage = -1; pg_lastcp = NULL; } void pg_draw(state) struct render_state *state; { char buf[BUFSIZ], *p; int n; u_int page; int showlast; if (!pg_mode || !pg_win || !plfs) return; page = state->page; #if 0 if (page == pg_lastpage && state->cp == pg_lastcp) return; #endif if (page == pg_lastpage) return; if (!state->cp) { pg_clean(); return; } showlast = (state->cp->ct_op == CTL_PAUSE && state->cp->cti_value); XSetForeground(display, gc_pta, ctrl_color[caching]); XSetForeground(display, gc_ptk, ctrl_color[caching]); XSetBackground(display, gc_pta, back_color[caching]); XSetBackground(display, gc_ptk, back_color[caching]); pg_clean(); if (page > 1) { sprintf(buf, "\033$B\"+\033(B %s", page_title(page - 1)); draw_kstring(pg_win, buf, PL_X_MARGIN, pl_fh - plfs->max_bounds.descent); } if (page < maxpage) { sprintf(buf, "%s\033$B\"*\033(B", page_title(page + 1)); for (p = buf; *p; p++) if (*p == '\n') *p = ' '; n = draw_kstring(pg_tmp, buf, 0, pl_fh); sprintf(buf, "%s\033$B\"*\033(B", page_title(page + 1)); for (p = buf; *p; p++) if (*p == '\n') *p = ' '; draw_kstring(pg_win, buf, window_width - 10 - n, pl_fh - plfs->max_bounds.descent); } if (showlast == 0) { sprintf(buf, "-- %d/%d --", page, maxpage); n = draw_kstring(pg_tmp, buf, 0, pl_fh); /* * The contents of buf is not destroyed by draw_kstring * as it doesnot include Kanji sequence. */ draw_kstring(pg_win, buf, window_width / 2 - n / 2, pl_fh - plfs->max_bounds.descent); } pg_lastpage = state->page; pg_lastcp = state->cp; } void pg_off() { if (!pg_win) return; XUnmapSubwindows(display, window); XFreePixmap(display, pg_tmp); XDestroyWindow(display, pg_win); XMapSubwindows(display, window); XFlush(display); pg_win = None; pg_lastpage = -1; pg_lastcp = NULL; } static int draw_kstring(d, buf, x, y) Drawable d; char *buf; int x, y; { char *p; int x0 = x; p = buf + strlen(buf) - 1; if (*p == '\n') *p = '\0'; for (p = buf; *p; p++) { if (strncmp(p, "\033$@", 3) == 0 || strncmp(p, "\033$B", 3) == 0) { *p = '\0'; p += 3; /* draw 8bit char */ XDrawImageString(display, d, gc_pta, x, y, buf, strlen(buf)); x += XTextWidth(plfs, buf, strlen(buf)); buf = p--; } else if (strncmp(p, "\033(B", 3) == 0 || strncmp(p, "\033(J", 3) == 0) { *p = '\0'; p += 3; /* draw 16bit char */ XDrawImageString16(display, d, gc_ptk, x, y, (XChar2b *)buf, strlen(buf)/2); x += XTextWidth16(plkfs, (XChar2b *)buf, strlen(buf)/2); buf = p--; } } /* draw 8bit char */ if (*buf != '\0') { /* Assumed ASCII at the end of string */ XDrawImageString(display, d, gc_pta, x, y, buf, strlen(buf)); x += XTextWidth(plfs, buf, strlen(buf)); } return x - x0; }