/*
* 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;
}
syntax highlighted by Code2HTML, v. 0.9.1