Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 7533 → Rev 7532

/contrib/media/updf/apps/kos_main.c
67,12 → 67,7
asm ("int $0x40"::"a"(73),"b"(0),"c"(&image));
}
 
void run_app()
{
return;
}
 
 
int __menuet__get_mouse_wheels(void)
{
int val;
150,7 → 145,6
{
char *r = "";
return r;
random();
}
 
 
173,12 → 167,7
__menuet__sys_exit();
}
 
void RunOpenApp()
{
RunApp("/sys/lod", "*pdf* /kolibrios/media/updf");
}
 
 
void winrepaint(pdfapp_t *app)
{
winblit(&gapp);
269,13 → 258,6
{
char ii, mouse_wheels_state;
char* original_command_line = *(char**)0x1C;
if (*original_command_line == 0) {
kol_board_puts("Running uPDF without any param");
RunOpenApp();
__menuet__sys_exit();
}
 
kol_board_puts(original_command_line);
kol_board_puts("\n");
343,7 → 325,7
case evButton:
butt = __menuet__get_button_id();
if(butt==1) __menuet__sys_exit();
if(butt==10) RunOpenApp();
if(butt==10) RunApp("/sys/lod", "*pdf* /kolibrios/media/updf");
if(butt==11) PageZoomOut(); //magnify -
if(butt==12) PageZoomIn(); //magnify +
if(butt==13) //show help
/contrib/media/updf/apps/man/mupdf.1
0,0 → 1,86
.TH MUPDF 1 "March 15, 2010"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
mupdf \- MuPDF is a lightweight PDF viewer written in portable C
.SH SYNOPSIS
.B mupdf
.RI [ options ] " PDFfile"
.SH DESCRIPTION
This manual page briefly describes the
.B mupdf
command.
.PP
.SH OPTIONS
A description of each of the supported options is included below.
.TP
.B \-p password
Uses the given password to open an encrypted PDF file.
The password is tried both as user and owner password.
.TP
.B \-r resolution
Changes the initial zoom level, specified as the resolution in dpi.
The default value is 72.
.SH MOUSE AND KEY BINDINGS
In addition to the key bindings described below, the mouse can also be
used. Clicking the left mouse button follows links within the PDF while
dragging with the left mouse button pans the page. Dragging with the right
mouse button selects an area and copies the enclosed text to the clipboard
buffer. Using the scroll-wheel while pressing Control zooms in/out, if
Shift is pressed on the other hand then the page is panned.
.TP
.B L, R
Rotate page left (clockwise) or right (counter-clockwise).
.TP
.B h, j, k, l
Scroll page left, down, up, or right.
.TP
.B \+, \-
Zoom in or out.
.TP
.B w
Shrinkwrap window to fit the page.
.TP
.B r
Reload file.
.TP
.B . pgdn right space
Go to the next page
.TP
.B , pgup left b
Go to the previous page
.TP
.B <, >
Skip back/forth 10 pages at a time.
.TP
.B m
Mark page for snap back.
.TP
.B t
Pop back to the latest mark.
.TP
.B [0-9]m
Save the current page number in the numbered register.
.TP
.B [0-9]t
Go to the page saved in the numbered register.
.TP
.B 123g
Go to page 123.
.TP
.B /
Search for text.
.TP
.B n, N
Find the next/previous search result.
.TP
.B c
Toggle between color and grayscale rendering.
.SH SEE ALSO
.BR pdfclean (1),
.BR pdfdraw (1),
.BR pdfshow (1).
.SH AUTHOR
MuPDF was written by Tor Andersson <tor@ghostscript.com>.
MuPDF is Copyright 2006-2010 Artifex Software, Inc.
.PP
This manual page was written by Sebastian Rasmussen <sebras@hotmail.com>.
/contrib/media/updf/apps/man/pdfclean.1
0,0 → 1,39
.TH PDFCLEAN 1 "September 4, 2011"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
pdfclean \- pretty print, decompress and garbage collect PDF files
.SH SYNOPSIS
.B pdfclean
.RI [ options ]
.RI input.pdf
.RI [ output.pdf ]
.RI [ pages ]
.SH DESCRIPTION
.B pdfclean
pretty prints and rewrites the contents of a PDF file.
If no output file is specified, the new file will be written to "out.pdf" in
the current directory.
.PP
.SH OPTIONS
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B \-g
Garbage collect objects that have no references from other objects.
Give the option twice to renumber all objects and compact the cross reference table.
Give it three times to merge and reuse duplicate objects.
.TP
.B \-d
Decompress streams. This will make the output file larger, but provides
easy access for reading and editing the contents with a text editor.
.TP
.B pages
Comma separated list of ranges to clean.
.SH SEE ALSO
.BR mupdf (1),
.BR pdfdraw (1).
.BR pdfshow (1).
.SH AUTHOR
MuPDF was written by Tor Andersson <tor@ghostscript.com>.
MuPDF is Copyright 2006-2010 Artifex Software, Inc.
/contrib/media/updf/apps/man/pdfdraw.1
0,0 → 1,78
.TH PDFDRAW 1 "September 4, 2011"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
pdfdraw \- render PDF documents
.SH SYNOPSIS
.B pdfdraw
.RI [ options ]
.RI input.pdf
.RI [ pages]
.SH DESCRIPTION
.B pdfdraw
will render a PDF document to image files.
The supported image formats are: pgm, ppm, pam and png.
Select the pages to be rendered by specifying a comma
separated list of ranges and individual page numbers (for example: 1,5,10-15).
In no pages are specified all the pages will be rendered.
.SH OPTIONS
.TP
.B \-o output
The image format is deduced from the output file name.
Embed %d in the name to indicate the page number (for example: "page%d.png").
.TP
.B \-p password
Use the specified password if the file is encrypted.
.TP
.B \-r resolution
Render the page at the specified resolution.
The default resolution is 72 dpi.
.TP
.B \-R angle
Rotate clockwise by given number of degrees.
.TP
.B \-a
Save the alpha channel.
The default behavior is to render each page with a white background.
With this option, the page background is transparent.
Only supported for pam and png output formats.
.TP
.B \-g
Render in grayscale.
The default is to render a full color RGB image.
If the output format is pgm or ppm this option is ignored.
.TP
.B \-m
Show timing information.
Take the time it takes for each page to render and print
a summary at the end.
.TP
.B \-5
Print an MD5 checksum of the rendered image data for each page.
.TP
.B \-t
Print the text contents of each page in UTF-8 encoding.
Give the option twice to print detailed information
about the location of each character in XML format.
.TP
.B \-x
Print the display list used to render each page.
.TP
.B \-A
Disable the use of accelerated functions.
.TP
.B \-G gamma
Gamma correct the output image.
Some typical values are 0.7 or 1.4 to thin or darken text rendering.
.TP
.B \-I
Invert the output image colors.
.TP
.B pages
Comma separated list of ranges to render.
.SH SEE ALSO
.BR mupdf (1),
.BR pdfclean (1).
.BR pdfshow (1).
.SH AUTHOR
MuPDF was written by Tor Andersson <tor@ghostscript.com>.
MuPDF is Copyright 2006-2010 Artifex Software, Inc.
/contrib/media/updf/apps/man/pdfshow.1
0,0 → 1,42
.TH PDFSHOW 1 "July 19, 2010"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
pdfshow \- show objects and streams that make up a PDF document
.SH SYNOPSIS
.B pdfshow
.RI [ options ]
.RI file.pdf
.RI [ xref ]
.RI [ trailer ]
.RI [ pages ]
.RI [ grep ]
.RI [ object-number... ]
.SH DESCRIPTION
.B pdfshow
pretty prints the objects and streams specified on the command line.
Streams are decoded and non-printable characters are represented
with a period.
Specify objects with their number.
The special names xref, trailer and pages will
respectively print the cross reference, trailer,
and the object numbers for all pages.
The special name grep will print all objects in the file
in a compact one-line format suitable for piping to grep.
.PP
.SH OPTIONS
.TP
.B \-b
Print streams as binary data and omit the object header.
.TP
.B \-e
Print streams in their original encoded form.
.TP
.B \-p password
Use the specified password if the file is encrypted.
.SH SEE ALSO
.BR mupdf (1),
.BR pdfclean (1).
.BR pdfdraw (1).
.SH AUTHOR
MuPDF was written by Tor Andersson <tor@ghostscript.com>.
MuPDF is copyright 2006-2010 Artifex Software, Inc.
/contrib/media/updf/apps/mupdf_icon_antialias.ico
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/updf/apps/mupdf_icon_bitmap.ico
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/contrib/media/updf/apps/win_main.c
0,0 → 1,895
#include "fitz.h"
#include "mupdf.h"
#include "muxps.h"
#include "pdfapp.h"
 
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commdlg.h>
#include <shellapi.h>
 
#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
 
#define ID_ABOUT 0x1000
#define ID_DOCINFO 0x1001
 
static HWND hwndframe = NULL;
static HWND hwndview = NULL;
static HDC hdc;
static HBRUSH bgbrush;
static HBRUSH shbrush;
static BITMAPINFO *dibinf;
static HCURSOR arrowcurs, handcurs, waitcurs;
static LRESULT CALLBACK frameproc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK viewproc(HWND, UINT, WPARAM, LPARAM);
 
static int justcopied = 0;
 
static pdfapp_t gapp;
 
static wchar_t wbuf[1024];
static char filename[1024];
 
/*
* Create registry keys to associate MuPDF with PDF and XPS files.
*/
 
#define OPEN_KEY(parent, name, ptr) \
RegCreateKeyExA(parent, name, 0, 0, 0, KEY_WRITE, 0, &ptr, 0)
 
#define SET_KEY(parent, name, value) \
RegSetValueExA(parent, name, 0, REG_SZ, value, strlen(value) + 1)
 
void install_app(char *argv0)
{
char buf[512];
HKEY software, classes, mupdf, dotpdf, dotxps;
HKEY shell, open, command, supported_types;
HKEY pdf_progids, xps_progids;
 
OPEN_KEY(HKEY_CURRENT_USER, "Software", software);
OPEN_KEY(software, "Classes", classes);
OPEN_KEY(classes, ".pdf", dotpdf);
OPEN_KEY(dotpdf, "OpenWithProgids", pdf_progids);
OPEN_KEY(classes, ".xps", dotxps);
OPEN_KEY(dotxps, "OpenWithProgids", xps_progids);
OPEN_KEY(classes, "MuPDF", mupdf);
OPEN_KEY(mupdf, "SupportedTypes", supported_types);
OPEN_KEY(mupdf, "shell", shell);
OPEN_KEY(shell, "open", open);
OPEN_KEY(open, "command", command);
 
sprintf(buf, "\"%s\" \"%%1\"", argv0);
 
SET_KEY(open, "FriendlyAppName", "MuPDF");
SET_KEY(command, "", buf);
SET_KEY(supported_types, ".pdf", "");
SET_KEY(supported_types, ".xps", "");
SET_KEY(pdf_progids, "MuPDF", "");
SET_KEY(xps_progids, "MuPDF", "");
 
RegCloseKey(dotxps);
RegCloseKey(dotpdf);
RegCloseKey(mupdf);
RegCloseKey(classes);
RegCloseKey(software);
}
 
/*
* Dialog boxes
*/
 
void winwarn(pdfapp_t *app, char *msg)
{
MessageBoxA(hwndframe, msg, "MuPDF: Warning", MB_ICONWARNING);
}
 
void winerror(pdfapp_t *app, fz_error error)
{
char msgbuf[160 * 30];
int i;
 
/* TODO: redirect stderr to a log file and display here */
fz_catch(error, "displaying error message to user");
 
fz_strlcpy(msgbuf, "An error has occurred.\n\n", sizeof msgbuf);
for (i = 0; i < fz_get_error_count(); i++)
{
fz_strlcat(msgbuf, fz_get_error_line(i), sizeof msgbuf);
fz_strlcat(msgbuf, "\n", sizeof msgbuf);
}
 
MessageBoxA(hwndframe, msgbuf, "MuPDF: Error", MB_ICONERROR);
exit(1);
}
 
void win32error(char *msg)
{
LPSTR buf;
int code = GetLastError();
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&buf, 0, NULL);
winerror(&gapp, fz_throw("%s:\n%s", msg, buf));
}
 
int winfilename(wchar_t *buf, int len)
{
OPENFILENAME ofn;
buf[0] = 0;
memset(&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwndframe;
ofn.lpstrFile = buf;
ofn.nMaxFile = len;
ofn.lpstrInitialDir = NULL;
ofn.lpstrTitle = L"MuPDF: Open PDF file";
ofn.lpstrFilter = L"Documents (*.pdf;*.xps)\0*.xps;*.pdf\0PDF Files (*.pdf)\0*.pdf\0XPS Files (*.xps)\0*.xps\0All Files\0*\0\0";
ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY;
return GetOpenFileNameW(&ofn);
}
 
static char pd_filename[256] = "The file is encrypted.";
static char pd_password[256] = "";
static int pd_okay = 0;
 
INT CALLBACK
dlogpassproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
SetDlgItemTextA(hwnd, 4, pd_filename);
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case 1:
pd_okay = 1;
GetDlgItemTextA(hwnd, 3, pd_password, sizeof pd_password);
EndDialog(hwnd, 1);
return TRUE;
case 2:
pd_okay = 0;
EndDialog(hwnd, 1);
return TRUE;
}
break;
}
return FALSE;
}
 
char *winpassword(pdfapp_t *app, char *filename)
{
char buf[1024], *s;
int code;
strcpy(buf, filename);
s = buf;
if (strrchr(s, '\\')) s = strrchr(s, '\\') + 1;
if (strrchr(s, '/')) s = strrchr(s, '/') + 1;
if (strlen(s) > 32)
strcpy(s + 30, "...");
sprintf(pd_filename, "The file \"%s\" is encrypted.", s);
code = DialogBoxW(NULL, L"IDD_DLOGPASS", hwndframe, dlogpassproc);
if (code <= 0)
win32error("cannot create password dialog");
if (pd_okay)
return pd_password;
return NULL;
}
 
INT CALLBACK
dloginfoproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
char buf[256];
pdf_xref *xref = gapp.xref;
fz_obj *info, *obj;
 
switch(message)
{
case WM_INITDIALOG:
 
SetDlgItemTextW(hwnd, 0x10, wbuf);
 
if (!xref)
{
SetDlgItemTextA(hwnd, 0x11, "XPS");
SetDlgItemTextA(hwnd, 0x12, "None");
SetDlgItemTextA(hwnd, 0x13, "n/a");
return TRUE;
}
 
sprintf(buf, "PDF %d.%d", xref->version / 10, xref->version % 10);
SetDlgItemTextA(hwnd, 0x11, buf);
 
if (xref->crypt)
{
sprintf(buf, "Standard V%d %d-bit %s", pdf_get_crypt_revision(xref),
pdf_get_crypt_length(xref), pdf_get_crypt_method(xref));
SetDlgItemTextA(hwnd, 0x12, buf);
strcpy(buf, "");
if (pdf_has_permission(xref, PDF_PERM_PRINT))
strcat(buf, "print, ");
if (pdf_has_permission(xref, PDF_PERM_CHANGE))
strcat(buf, "modify, ");
if (pdf_has_permission(xref, PDF_PERM_COPY))
strcat(buf, "copy, ");
if (pdf_has_permission(xref, PDF_PERM_NOTES))
strcat(buf, "annotate, ");
if (strlen(buf) > 2)
buf[strlen(buf)-2] = 0;
else
strcpy(buf, "none");
SetDlgItemTextA(hwnd, 0x13, buf);
}
else
{
SetDlgItemTextA(hwnd, 0x12, "None");
SetDlgItemTextA(hwnd, 0x13, "n/a");
}
 
info = fz_dict_gets(xref->trailer, "Info");
if (!info)
return TRUE;
 
#define SETUCS(ID) \
{ \
unsigned short *ucs; \
ucs = pdf_to_ucs2(obj); \
SetDlgItemTextW(hwnd, ID, ucs); \
fz_free(ucs); \
}
 
if ((obj = fz_dict_gets(info, "Title")))
SETUCS(0x20);
if ((obj = fz_dict_gets(info, "Author")))
SETUCS(0x21);
if ((obj = fz_dict_gets(info, "Subject")))
SETUCS(0x22);
if ((obj = fz_dict_gets(info, "Keywords")))
SETUCS(0x23);
if ((obj = fz_dict_gets(info, "Creator")))
SETUCS(0x24);
if ((obj = fz_dict_gets(info, "Producer")))
SETUCS(0x25);
if ((obj = fz_dict_gets(info, "CreationDate")))
SETUCS(0x26);
if ((obj = fz_dict_gets(info, "ModDate")))
SETUCS(0x27);
return TRUE;
 
case WM_COMMAND:
EndDialog(hwnd, 1);
return TRUE;
}
return FALSE;
}
 
void info()
{
int code = DialogBoxW(NULL, L"IDD_DLOGINFO", hwndframe, dloginfoproc);
if (code <= 0)
win32error("cannot create info dialog");
}
 
INT CALLBACK
dlogaboutproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_INITDIALOG:
SetDlgItemTextA(hwnd, 2, pdfapp_version(&gapp));
SetDlgItemTextA(hwnd, 3, pdfapp_usage(&gapp));
return TRUE;
case WM_COMMAND:
EndDialog(hwnd, 1);
return TRUE;
}
return FALSE;
}
 
void winhelp(pdfapp_t*app)
{
int code = DialogBoxW(NULL, L"IDD_DLOGABOUT", hwndframe, dlogaboutproc);
if (code <= 0)
win32error("cannot create help dialog");
}
 
/*
* Main window
*/
 
void winopen()
{
WNDCLASS wc;
HMENU menu;
RECT r;
ATOM a;
 
/* Create and register window frame class */
memset(&wc, 0, sizeof(wc));
wc.style = 0;
wc.lpfnWndProc = frameproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = LoadIconA(wc.hInstance, "IDI_ICONAPP");
wc.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = L"FrameWindow";
a = RegisterClassW(&wc);
if (!a)
win32error("cannot register frame window class");
 
/* Create and register window view class */
memset(&wc, 0, sizeof(wc));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = viewproc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(NULL);
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = L"ViewWindow";
a = RegisterClassW(&wc);
if (!a)
win32error("cannot register view window class");
 
/* Get screen size */
SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
gapp.scrw = r.right - r.left;
gapp.scrh = r.bottom - r.top;
 
/* Create cursors */
arrowcurs = LoadCursor(NULL, IDC_ARROW);
handcurs = LoadCursor(NULL, IDC_HAND);
waitcurs = LoadCursor(NULL, IDC_WAIT);
 
/* And a background color */
bgbrush = CreateSolidBrush(RGB(0x70,0x70,0x70));
shbrush = CreateSolidBrush(RGB(0x40,0x40,0x40));
 
/* Init DIB info for buffer */
dibinf = malloc(sizeof(BITMAPINFO) + 12);
assert(dibinf != NULL);
dibinf->bmiHeader.biSize = sizeof(dibinf->bmiHeader);
dibinf->bmiHeader.biPlanes = 1;
dibinf->bmiHeader.biBitCount = 32;
dibinf->bmiHeader.biCompression = BI_RGB;
dibinf->bmiHeader.biXPelsPerMeter = 2834;
dibinf->bmiHeader.biYPelsPerMeter = 2834;
dibinf->bmiHeader.biClrUsed = 0;
dibinf->bmiHeader.biClrImportant = 0;
dibinf->bmiHeader.biClrUsed = 0;
 
/* Create window */
hwndframe = CreateWindowW(L"FrameWindow", // window class name
NULL, // window caption
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT, // initial position
300, // initial x size
300, // initial y size
0, // parent window handle
0, // window menu handle
0, // program instance handle
0); // creation parameters
if (!hwndframe)
win32error("cannot create frame: %s");
 
hwndview = CreateWindowW(L"ViewWindow", // window class name
NULL,
WS_VISIBLE | WS_CHILD,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hwndframe, 0, 0, 0);
if (!hwndview)
win32error("cannot create view: %s");
 
hdc = NULL;
 
SetWindowTextW(hwndframe, L"MuPDF");
 
menu = GetSystemMenu(hwndframe, 0);
AppendMenuW(menu, MF_SEPARATOR, 0, NULL);
AppendMenuW(menu, MF_STRING, ID_ABOUT, L"About MuPDF...");
AppendMenuW(menu, MF_STRING, ID_DOCINFO, L"Document Properties...");
 
SetCursor(arrowcurs);
}
 
void winclose(pdfapp_t *app)
{
pdfapp_close(app);
exit(0);
}
 
void wincursor(pdfapp_t *app, int curs)
{
if (curs == ARROW)
SetCursor(arrowcurs);
if (curs == HAND)
SetCursor(handcurs);
if (curs == WAIT)
SetCursor(waitcurs);
}
 
void wintitle(pdfapp_t *app, char *title)
{
wchar_t wide[256], *dp;
char *sp;
int rune;
 
dp = wide;
sp = title;
while (*sp && dp < wide + 255)
{
sp += chartorune(&rune, sp);
*dp++ = rune;
}
*dp = 0;
 
SetWindowTextW(hwndframe, wide);
}
 
void windrawrect(pdfapp_t *app, int x0, int y0, int x1, int y1)
{
RECT r;
r.left = x0;
r.top = y0;
r.right = x1;
r.bottom = y1;
FillRect(hdc, &r, (HBRUSH)GetStockObject(WHITE_BRUSH));
}
 
void windrawstring(pdfapp_t *app, int x, int y, char *s)
{
HFONT font = (HFONT)GetStockObject(ANSI_FIXED_FONT);
SelectObject(hdc, font);
TextOutA(hdc, x, y - 12, s, strlen(s));
}
 
void winblitsearch()
{
if (gapp.isediting)
{
char buf[sizeof(gapp.search) + 50];
sprintf(buf, "Search: %s", gapp.search);
windrawrect(&gapp, 0, 0, gapp.winw, 30);
windrawstring(&gapp, 10, 20, buf);
}
}
 
void winblit()
{
int x0 = gapp.panx;
int y0 = gapp.pany;
int x1 = gapp.panx + gapp.image->w;
int y1 = gapp.pany + gapp.image->h;
RECT r;
 
if (gapp.image)
{
if (gapp.iscopying || justcopied)
{
pdfapp_invert(&gapp, gapp.selr);
justcopied = 1;
}
 
pdfapp_inverthit(&gapp);
 
dibinf->bmiHeader.biWidth = gapp.image->w;
dibinf->bmiHeader.biHeight = -gapp.image->h;
dibinf->bmiHeader.biSizeImage = gapp.image->h * 4;
 
if (gapp.image->n == 2)
{
int i = gapp.image->w * gapp.image->h;
unsigned char *color = malloc(i*4);
unsigned char *s = gapp.image->samples;
unsigned char *d = color;
for (; i > 0 ; i--)
{
d[2] = d[1] = d[0] = *s++;
d[3] = *s++;
d += 4;
}
SetDIBitsToDevice(hdc,
gapp.panx, gapp.pany, gapp.image->w, gapp.image->h,
0, 0, 0, gapp.image->h, color,
dibinf, DIB_RGB_COLORS);
free(color);
}
if (gapp.image->n == 4)
{
SetDIBitsToDevice(hdc,
gapp.panx, gapp.pany, gapp.image->w, gapp.image->h,
0, 0, 0, gapp.image->h, gapp.image->samples,
dibinf, DIB_RGB_COLORS);
}
 
pdfapp_inverthit(&gapp);
 
if (gapp.iscopying || justcopied)
{
pdfapp_invert(&gapp, gapp.selr);
justcopied = 1;
}
}
 
/* Grey background */
r.top = 0; r.bottom = gapp.winh;
r.left = 0; r.right = x0;
FillRect(hdc, &r, bgbrush);
r.left = x1; r.right = gapp.winw;
FillRect(hdc, &r, bgbrush);
r.left = 0; r.right = gapp.winw;
r.top = 0; r.bottom = y0;
FillRect(hdc, &r, bgbrush);
r.top = y1; r.bottom = gapp.winh;
FillRect(hdc, &r, bgbrush);
 
/* Drop shadow */
r.left = x0 + 2;
r.right = x1 + 2;
r.top = y1;
r.bottom = y1 + 2;
FillRect(hdc, &r, shbrush);
r.left = x1;
r.right = x1 + 2;
r.top = y0 + 2;
r.bottom = y1;
FillRect(hdc, &r, shbrush);
 
winblitsearch();
}
 
void winresize(pdfapp_t *app, int w, int h)
{
ShowWindow(hwndframe, SW_SHOWDEFAULT);
w += GetSystemMetrics(SM_CXFRAME) * 2;
h += GetSystemMetrics(SM_CYFRAME) * 2;
h += GetSystemMetrics(SM_CYCAPTION);
SetWindowPos(hwndframe, 0, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE);
}
 
void winrepaint(pdfapp_t *app)
{
InvalidateRect(hwndview, NULL, 0);
}
 
void winrepaintsearch(pdfapp_t *app)
{
// TODO: invalidate only search area and
// call only search redraw routine.
InvalidateRect(hwndview, NULL, 0);
}
 
/*
* Event handling
*/
 
void windocopy(pdfapp_t *app)
{
HGLOBAL handle;
unsigned short *ucsbuf;
 
if (!OpenClipboard(hwndframe))
return;
EmptyClipboard();
 
handle = GlobalAlloc(GMEM_MOVEABLE, 4096 * sizeof(unsigned short));
if (!handle)
{
CloseClipboard();
return;
}
 
ucsbuf = GlobalLock(handle);
pdfapp_oncopy(&gapp, ucsbuf, 4096);
GlobalUnlock(handle);
 
SetClipboardData(CF_UNICODETEXT, handle);
CloseClipboard();
 
justcopied = 1; /* keep inversion around for a while... */
}
 
void winreloadfile(pdfapp_t *app)
{
int fd;
 
pdfapp_close(app);
 
fd = _wopen(wbuf, O_BINARY | O_RDONLY, 0666);
if (fd < 0)
winerror(&gapp, fz_throw("cannot reload file '%s'", filename));
 
pdfapp_open(app, filename, fd, 1);
}
 
void winopenuri(pdfapp_t *app, char *buf)
{
ShellExecuteA(hwndframe, "open", buf, 0, 0, SW_SHOWNORMAL);
}
 
void handlekey(int c)
{
if (GetCapture() == hwndview)
return;
 
if (justcopied)
{
justcopied = 0;
winrepaint(&gapp);
}
 
/* translate VK into ascii equivalents */
if (c > 256)
{
switch (c - 256)
{
case VK_F1: c = '?'; break;
case VK_ESCAPE: c = '\033'; break;
case VK_DOWN: c = 'j'; break;
case VK_UP: c = 'k'; break;
case VK_LEFT: c = 'b'; break;
case VK_RIGHT: c = ' '; break;
case VK_PRIOR: c = ','; break;
case VK_NEXT: c = '.'; break;
}
}
 
pdfapp_onkey(&gapp, c);
winrepaint(&gapp);
}
 
void handlemouse(int x, int y, int btn, int state)
{
if (state != 0 && justcopied)
{
justcopied = 0;
winrepaint(&gapp);
}
 
if (state == 1)
SetCapture(hwndview);
if (state == -1)
ReleaseCapture();
 
pdfapp_onmouse(&gapp, x, y, btn, 0, state);
}
 
LRESULT CALLBACK
frameproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_SETFOCUS:
PostMessage(hwnd, WM_APP+5, 0, 0);
return 0;
case WM_APP+5:
SetFocus(hwndview);
return 0;
 
case WM_DESTROY:
PostQuitMessage(0);
return 0;
 
case WM_SYSCOMMAND:
if (wParam == ID_ABOUT)
{
winhelp(&gapp);
return 0;
}
if (wParam == ID_DOCINFO)
{
info();
return 0;
}
if (wParam == SC_MAXIMIZE)
gapp.shrinkwrap = 0;
break;
 
case WM_SIZE:
{
// More generally, you should use GetEffectiveClientRect
// if you have a toolbar etc.
RECT rect;
GetClientRect(hwnd, &rect);
MoveWindow(hwndview, rect.left, rect.top,
rect.right-rect.left, rect.bottom-rect.top, TRUE);
return 0;
}
 
case WM_SIZING:
gapp.shrinkwrap = 0;
break;
 
case WM_NOTIFY:
case WM_COMMAND:
return SendMessage(hwndview, message, wParam, lParam);
}
 
return DefWindowProc(hwnd, message, wParam, lParam);
}
 
LRESULT CALLBACK
viewproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static int oldx = 0;
static int oldy = 0;
int x = (signed short) LOWORD(lParam);
int y = (signed short) HIWORD(lParam);
 
switch (message)
{
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
return 0;
if (wParam == SIZE_MAXIMIZED)
gapp.shrinkwrap = 0;
pdfapp_onresize(&gapp, LOWORD(lParam), HIWORD(lParam));
break;
 
/* Paint events are low priority and automagically catenated
* so we don't need to do any fancy waiting to defer repainting.
*/
case WM_PAINT:
{
//puts("WM_PAINT");
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
winblit();
hdc = NULL;
EndPaint(hwnd, &ps);
return 0;
}
 
case WM_ERASEBKGND:
return 1; // well, we don't need to erase to redraw cleanly
 
/* Mouse events */
 
case WM_LBUTTONDOWN:
SetFocus(hwndview);
oldx = x; oldy = y;
handlemouse(x, y, 1, 1);
return 0;
case WM_MBUTTONDOWN:
SetFocus(hwndview);
oldx = x; oldy = y;
handlemouse(x, y, 2, 1);
return 0;
case WM_RBUTTONDOWN:
SetFocus(hwndview);
oldx = x; oldy = y;
handlemouse(x, y, 3, 1);
return 0;
 
case WM_LBUTTONUP:
oldx = x; oldy = y;
handlemouse(x, y, 1, -1);
return 0;
case WM_MBUTTONUP:
oldx = x; oldy = y;
handlemouse(x, y, 2, -1);
return 0;
case WM_RBUTTONUP:
oldx = x; oldy = y;
handlemouse(x, y, 3, -1);
return 0;
 
case WM_MOUSEMOVE:
oldx = x; oldy = y;
handlemouse(x, y, 0, 0);
return 0;
 
/* Mouse wheel */
 
case WM_MOUSEWHEEL:
if ((signed short)HIWORD(wParam) > 0)
handlekey(LOWORD(wParam) & MK_SHIFT ? '+' : 'k');
else
handlekey(LOWORD(wParam) & MK_SHIFT ? '-' : 'j');
return 0;
 
/* Keyboard events */
 
case WM_KEYDOWN:
/* only handle special keys */
switch (wParam)
{
case VK_F1:
case VK_LEFT:
case VK_UP:
case VK_PRIOR:
case VK_RIGHT:
case VK_DOWN:
case VK_NEXT:
case VK_ESCAPE:
handlekey(wParam + 256);
handlemouse(oldx, oldy, 0, 0); /* update cursor */
return 0;
}
return 1;
 
/* unicode encoded chars, including escape, backspace etc... */
case WM_CHAR:
if (wParam < 256)
{
handlekey(wParam);
handlemouse(oldx, oldy, 0, 0); /* update cursor */
}
return 0;
}
 
fflush(stdout);
 
/* Pass on unhandled events to Windows */
return DefWindowProc(hwnd, message, wParam, lParam);
}
 
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
int argc;
LPWSTR *argv = CommandLineToArgvW(GetCommandLineW(), &argc);
char argv0[256];
MSG msg;
int fd;
int code;
 
fz_accelerate();
 
pdfapp_init(&gapp);
 
GetModuleFileNameA(NULL, argv0, sizeof argv0);
install_app(argv0);
 
winopen();
 
if (argc == 2)
{
wcscpy(wbuf, argv[1]);
}
else
{
if (!winfilename(wbuf, nelem(wbuf)))
exit(0);
}
 
fd = _wopen(wbuf, O_BINARY | O_RDONLY, 0666);
if (fd < 0)
winerror(&gapp, fz_throw("cannot open file '%s'", filename));
 
code = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, filename, sizeof filename, NULL, NULL);
if (code == 0)
win32error("cannot convert filename to utf-8");
 
pdfapp_open(&gapp, filename, fd, 0);
 
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
 
pdfapp_close(&gapp);
 
return 0;
}
/contrib/media/updf/apps/win_res.rc
0,0 → 1,61
IDI_ICONAPP ICON "mupdf_icon_antialias.ico"
 
IDD_DLOGPASS DIALOG 50, 50, 204, 60
//STYLE DS_MODALFRAME | WS_POPUP
STYLE 128 | 0x80000000
CAPTION " MuPDF: Password "
FONT 8, "MS Shell Dlg"
BEGIN
EDITTEXT 3, 57, 20, 140, 12, 32
DEFPUSHBUTTON "Okay", 1, 90, 40, 50, 14, 0x50010001
PUSHBUTTON "Cancel", 2, 147, 40, 50, 14, 0x50010000
LTEXT "The file is encrypted.", 4, 10, 7, 180, 10, 0x00000
LTEXT "Password:", 5, 17, 22, 40, 10, 0x00000
END
 
IDD_DLOGINFO DIALOG 50, 50, 300, 145
STYLE 128 | 0x80000000
CAPTION " Document Properties "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Okay", 1, 300-10-50, 145-7-14, 50, 14, 0x50010001
 
LTEXT "File:", -1, 10, 10, 50, 10, 0
LTEXT "Format:", -1, 10, 20, 50, 10, 0
LTEXT "Encryption:", -1, 10, 30, 50, 10, 0
LTEXT "Permissions:", -1, 10, 40, 50, 10, 0
 
LTEXT "<file", 0x10, 60, 10, 230, 10, 0
LTEXT "<version", 0x11, 60, 20, 230, 10, 0
LTEXT "<encryption", 0x12, 60, 30, 230, 10, 0
LTEXT "<permissions", 0x13, 60, 40, 230, 10, 0
 
LTEXT "Title:", -1, 10, 55, 50, 10, 0
LTEXT "Author:", -1, 10, 65, 50, 10, 0
LTEXT "Subject:", -1, 10, 75, 50, 10, 0
LTEXT "Keywords:", -1, 10, 85, 50, 10, 0
LTEXT "Creator:", -1, 10, 95, 50, 10, 0
LTEXT "Producer:", -1, 10, 105, 50, 10, 0
LTEXT "Created:", -1, 10, 115, 50, 10, 0
LTEXT "Modified:", -1, 10, 125, 50, 10, 0
 
LTEXT "", 0x20, 60, 55, 230, 10, 0
LTEXT "", 0x21, 60, 65, 230, 10, 0
LTEXT "", 0x22, 60, 75, 230, 10, 0
LTEXT "", 0x23, 60, 85, 230, 10, 0
LTEXT "", 0x24, 60, 95, 230, 10, 0
LTEXT "", 0x25, 60, 105, 230, 10, 0
LTEXT "", 0x26, 60, 115, 100, 10, 0
LTEXT "", 0x27, 60, 125, 100, 10, 0
END
 
IDD_DLOGABOUT DIALOG 50, 50, 200, 220
STYLE 128 | 0x80000000
CAPTION " About MuPDF "
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Okay", 1, 200-10-50, 220-7-14, 50, 14, 0x50010001
LTEXT "<copyright>", 2, 10, 10, 180, 20, 0
LTEXT "<usage>", 3, 10, 35, 180, 160, 0
END
 
/contrib/media/updf/apps/x11_image.c
0,0 → 1,697
/*
* Blit RGBA images to X with X(Shm)Images
*/
 
#ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 1
#endif
 
#ifndef _XOPEN_SOURCE
# define _XOPEN_SOURCE 1
#endif
 
#define noSHOWINFO
 
#include "fitz.h"
 
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
 
extern int ffs(int);
 
typedef void (*ximage_convert_func_t)
(
const unsigned char *src,
int srcstride,
unsigned char *dst,
int dststride,
int w,
int h
);
 
#define POOLSIZE 4
#define WIDTH 256
#define HEIGHT 256
 
enum {
ARGB8888,
BGRA8888,
RGBA8888,
ABGR8888,
RGB888,
BGR888,
RGB565,
RGB565_BR,
RGB555,
RGB555_BR,
BGR233,
UNKNOWN
};
 
#ifdef SHOWINFO
static char *modename[] = {
"ARGB8888",
"BGRA8888",
"RGBA8888",
"ABGR8888",
"RGB888",
"BGR888",
"RGB565",
"RGB565_BR",
"RGB555",
"RGB555_BR",
"BGR233",
"UNKNOWN"
};
#endif
 
extern ximage_convert_func_t ximage_convert_funcs[];
 
static struct
{
Display *display;
int screen;
XVisualInfo visual;
Colormap colormap;
 
int bitsperpixel;
int mode;
 
XColor rgbcube[256];
 
ximage_convert_func_t convert_func;
 
int useshm;
int shmcode;
XImage *pool[POOLSIZE];
/* MUST exist during the lifetime of the shared ximage according to the
xc/doc/hardcopy/Xext/mit-shm.PS.gz */
XShmSegmentInfo shminfo[POOLSIZE];
int lastused;
} info;
 
static XImage *
createximage(Display *dpy, Visual *vis, XShmSegmentInfo *xsi, int depth, int w, int h)
{
XImage *img;
Status status;
 
if (!XShmQueryExtension(dpy))
goto fallback;
if (!info.useshm)
goto fallback;
 
img = XShmCreateImage(dpy, vis, depth, ZPixmap, NULL, xsi, w, h);
if (!img)
{
fprintf(stderr, "warn: could not XShmCreateImage\n");
goto fallback;
}
 
xsi->shmid = shmget(IPC_PRIVATE,
img->bytes_per_line * img->height,
IPC_CREAT | 0777);
if (xsi->shmid < 0)
{
XDestroyImage(img);
fprintf(stderr, "warn: could not shmget\n");
goto fallback;
}
 
img->data = xsi->shmaddr = shmat(xsi->shmid, NULL, 0);
if (img->data == (char*)-1)
{
XDestroyImage(img);
fprintf(stderr, "warn: could not shmat\n");
goto fallback;
}
 
xsi->readOnly = False;
status = XShmAttach(dpy, xsi);
if (!status)
{
shmdt(xsi->shmaddr);
XDestroyImage(img);
fprintf(stderr, "warn: could not XShmAttach\n");
goto fallback;
}
 
XSync(dpy, False);
 
shmctl(xsi->shmid, IPC_RMID, NULL);
 
return img;
 
fallback:
info.useshm = 0;
 
img = XCreateImage(dpy, vis, depth, ZPixmap, 0, NULL, w, h, 32, 0);
if (!img)
{
fprintf(stderr, "fail: could not XCreateImage");
abort();
}
 
img->data = malloc(h * img->bytes_per_line);
if (!img->data)
{
fprintf(stderr, "fail: could not malloc");
abort();
}
 
return img;
}
 
static void
make_colormap(void)
{
if (info.visual.class == PseudoColor && info.visual.depth == 8)
{
int i, r, g, b;
i = 0;
for (b = 0; b < 4; b++) {
for (g = 0; g < 8; g++) {
for (r = 0; r < 8; r++) {
info.rgbcube[i].pixel = i;
info.rgbcube[i].red = (r * 36) << 8;
info.rgbcube[i].green = (g * 36) << 8;
info.rgbcube[i].blue = (b * 85) << 8;
info.rgbcube[i].flags =
DoRed | DoGreen | DoBlue;
i++;
}
}
}
info.colormap = XCreateColormap(info.display,
RootWindow(info.display, info.screen),
info.visual.visual,
AllocAll);
XStoreColors(info.display, info.colormap, info.rgbcube, 256);
return;
}
else if (info.visual.class == TrueColor)
{
info.colormap = 0;
return;
}
fprintf(stderr, "Cannot handle visual class %d with depth: %d\n",
info.visual.class, info.visual.depth);
return;
}
 
static void
select_mode(void)
{
 
int byteorder;
int byterev;
unsigned long rm, gm, bm;
unsigned long rs, gs, bs;
 
byteorder = ImageByteOrder(info.display);
if (fz_is_big_endian())
byterev = byteorder != MSBFirst;
else
byterev = byteorder != LSBFirst;
 
rm = info.visual.red_mask;
gm = info.visual.green_mask;
bm = info.visual.blue_mask;
 
rs = ffs(rm) - 1;
gs = ffs(gm) - 1;
bs = ffs(bm) - 1;
 
#ifdef SHOWINFO
printf("ximage: mode %d/%d %08lx %08lx %08lx (%ld,%ld,%ld) %s%s\n",
info.visual.depth,
info.bitsperpixel,
rm, gm, bm, rs, gs, bs,
byteorder == MSBFirst ? "msb" : "lsb",
byterev ? " <swap>":"");
#endif
 
info.mode = UNKNOWN;
if (info.bitsperpixel == 8) {
/* Either PseudoColor with BGR233 colormap, or TrueColor */
info.mode = BGR233;
}
else if (info.bitsperpixel == 16) {
if (rm == 0xF800 && gm == 0x07E0 && bm == 0x001F)
info.mode = !byterev ? RGB565 : RGB565_BR;
if (rm == 0x7C00 && gm == 0x03E0 && bm == 0x001F)
info.mode = !byterev ? RGB555 : RGB555_BR;
}
else if (info.bitsperpixel == 24) {
if (rs == 0 && gs == 8 && bs == 16)
info.mode = byteorder == MSBFirst ? RGB888 : BGR888;
if (rs == 16 && gs == 8 && bs == 0)
info.mode = byteorder == MSBFirst ? BGR888 : RGB888;
}
else if (info.bitsperpixel == 32) {
if (rs == 0 && gs == 8 && bs == 16)
info.mode = byteorder == MSBFirst ? ABGR8888 : RGBA8888;
if (rs == 8 && gs == 16 && bs == 24)
info.mode = byteorder == MSBFirst ? BGRA8888 : ARGB8888;
if (rs == 16 && gs == 8 && bs == 0)
info.mode = byteorder == MSBFirst ? ARGB8888 : BGRA8888;
if (rs == 24 && gs == 16 && bs == 8)
info.mode = byteorder == MSBFirst ? RGBA8888 : ABGR8888;
}
 
#ifdef SHOWINFO
printf("ximage: RGBA8888 to %s\n", modename[info.mode]);
#endif
 
/* select conversion function */
info.convert_func = ximage_convert_funcs[info.mode];
}
 
static int
create_pool(void)
{
int i;
 
info.lastused = 0;
 
for (i = 0; i < POOLSIZE; i++) {
info.pool[i] = NULL;
}
 
for (i = 0; i < POOLSIZE; i++) {
info.pool[i] = createximage(info.display,
info.visual.visual, &info.shminfo[i], info.visual.depth,
WIDTH, HEIGHT);
if (info.pool[i] == NULL) {
return 0;
}
}
 
return 1;
}
 
static XImage *
next_pool_image(void)
{
if (info.lastused + 1 >= POOLSIZE) {
if (info.useshm)
XSync(info.display, False);
else
XFlush(info.display);
info.lastused = 0;
}
return info.pool[info.lastused ++];
}
 
static int
ximage_error_handler(Display *display, XErrorEvent *event)
{
/* Turn off shared memory images if we get an error from the MIT-SHM extension */
if (event->request_code == info.shmcode)
{
char buf[80];
XGetErrorText(display, event->error_code, buf, sizeof buf);
fprintf(stderr, "ximage: disabling shared memory extension: %s\n", buf);
info.useshm = 0;
return 0;
}
 
XSetErrorHandler(NULL);
return (XSetErrorHandler(ximage_error_handler))(display, event);
}
 
int
ximage_init(Display *display, int screen, Visual *visual)
{
XVisualInfo template;
XVisualInfo *visuals;
int nvisuals;
XPixmapFormatValues *formats;
int nformats;
int ok;
int i;
int major;
int event;
int error;
 
info.display = display;
info.screen = screen;
info.colormap = 0;
 
/* Get XVisualInfo for this visual */
template.visualid = XVisualIDFromVisual(visual);
visuals = XGetVisualInfo(display, VisualIDMask, &template, &nvisuals);
if (nvisuals != 1) {
fprintf(stderr, "Visual not found!\n");
XFree(visuals);
return 0;
}
memcpy(&info.visual, visuals, sizeof (XVisualInfo));
XFree(visuals);
 
/* Get appropriate PixmapFormat for this visual */
formats = XListPixmapFormats(info.display, &nformats);
for (i = 0; i < nformats; i++) {
if (formats[i].depth == info.visual.depth) {
info.bitsperpixel = formats[i].bits_per_pixel;
break;
}
}
XFree(formats);
if (i == nformats) {
fprintf(stderr, "PixmapFormat not found!\n");
return 0;
}
 
/* extract mode */
select_mode();
 
/* prepare colormap */
make_colormap();
 
/* identify code for MIT-SHM extension */
if (XQueryExtension(display, "MIT-SHM", &major, &event, &error) &&
XShmQueryExtension(display))
info.shmcode = major;
 
/* intercept errors looking for SHM code */
XSetErrorHandler(ximage_error_handler);
 
/* prepare pool of XImages */
info.useshm = 1;
ok = create_pool();
if (!ok)
return 0;
 
#ifdef SHOWINFO
printf("ximage: %sPutImage\n", info.useshm ? "XShm" : "X");
#endif
 
return 1;
}
 
int
ximage_get_depth(void)
{
return info.visual.depth;
}
 
Visual *
ximage_get_visual(void)
{
return info.visual.visual;
}
 
Colormap
ximage_get_colormap(void)
{
return info.colormap;
}
 
void
ximage_blit(Drawable d, GC gc,
int dstx, int dsty,
unsigned char *srcdata,
int srcx, int srcy,
int srcw, int srch,
int srcstride)
{
XImage *image;
int ax, ay;
int w, h;
unsigned char *srcptr;
 
for (ay = 0; ay < srch; ay += HEIGHT)
{
h = MIN(srch - ay, HEIGHT);
for (ax = 0; ax < srcw; ax += WIDTH)
{
w = MIN(srcw - ax, WIDTH);
 
image = next_pool_image();
 
srcptr = srcdata +
(ay + srcy) * srcstride +
(ax + srcx) * 4;
 
info.convert_func(srcptr, srcstride,
(unsigned char *) image->data,
image->bytes_per_line, w, h);
 
if (info.useshm)
{
XShmPutImage(info.display, d, gc, image,
0, 0, dstx + ax, dsty + ay,
w, h, False);
}
else
{
XPutImage(info.display, d, gc, image,
0, 0,
dstx + ax,
dsty + ay,
w, h);
}
}
}
}
 
/*
* Primitive conversion functions
*/
 
#ifndef restrict
#ifndef _C99
#ifdef __GNUC__
#define restrict __restrict__
#else
#define restrict
#endif
#endif
#endif
 
#define PARAMS \
const unsigned char * restrict src, \
int srcstride, \
unsigned char * restrict dst, \
int dststride, \
int w, \
int h
 
/*
* Convert byte:RGBA8888 to various formats
*/
 
static void
ximage_convert_argb8888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x ++) {
dst[x * 4 + 0] = src[x * 4 + 3]; /* a */
dst[x * 4 + 1] = src[x * 4 + 0]; /* r */
dst[x * 4 + 2] = src[x * 4 + 1]; /* g */
dst[x * 4 + 3] = src[x * 4 + 2]; /* b */
}
dst += dststride;
src += srcstride;
}
}
 
static void
ximage_convert_bgra8888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
dst[x * 4 + 0] = src[x * 4 + 2];
dst[x * 4 + 1] = src[x * 4 + 1];
dst[x * 4 + 2] = src[x * 4 + 0];
dst[x * 4 + 3] = src[x * 4 + 3];
}
dst += dststride;
src += srcstride;
}
}
 
static void
ximage_convert_abgr8888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
dst[x * 4 + 0] = src[x * 4 + 3];
dst[x * 4 + 1] = src[x * 4 + 2];
dst[x * 4 + 2] = src[x * 4 + 1];
dst[x * 4 + 3] = src[x * 4 + 0];
}
dst += dststride;
src += srcstride;
}
}
 
static void
ximage_convert_rgba8888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
dst[x] = src[x];
}
dst += dststride;
src += srcstride;
}
}
 
static void
ximage_convert_bgr888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
dst[3*x + 0] = src[4*x + 2];
dst[3*x + 1] = src[4*x + 1];
dst[3*x + 2] = src[4*x + 0];
}
src += srcstride;
dst += dststride;
}
}
 
static void
ximage_convert_rgb888(PARAMS)
{
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
dst[3*x + 0] = src[4*x + 0];
dst[3*x + 1] = src[4*x + 1];
dst[3*x + 2] = src[4*x + 2];
}
src += srcstride;
dst += dststride;
}
}
 
static void
ximage_convert_rgb565(PARAMS)
{
unsigned char r, g, b;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
r = src[4*x + 0];
g = src[4*x + 1];
b = src[4*x + 2];
((unsigned short *)dst)[x] =
((r & 0xF8) << 8) |
((g & 0xFC) << 3) |
(b >> 3);
}
src += srcstride;
dst += dststride;
}
}
 
static void
ximage_convert_rgb565_br(PARAMS)
{
unsigned char r, g, b;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
r = src[4*x + 0];
g = src[4*x + 1];
b = src[4*x + 2];
/* final word is:
g4 g3 g2 b7 b6 b5 b4 b3 : r7 r6 r5 r4 r3 g7 g6 g5
*/
((unsigned short *)dst)[x] =
(r & 0xF8) |
((g & 0xE0) >> 5) |
((g & 0x1C) << 11) |
((b & 0xF8) << 5);
}
src += srcstride;
dst += dststride;
}
}
 
static void
ximage_convert_rgb555(PARAMS)
{
unsigned char r, g, b;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
r = src[4*x + 0];
g = src[4*x + 1];
b = src[4*x + 2];
((unsigned short *)dst)[x] =
((r & 0xF8) << 7) |
((g & 0xF8) << 2) |
(b >> 3);
}
src += srcstride;
dst += dststride;
}
}
 
static void
ximage_convert_rgb555_br(PARAMS)
{
unsigned char r, g, b;
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
r = src[4*x + 0];
g = src[4*x + 1];
b = src[4*x + 2];
/* final word is:
g5 g4 g3 b7 b6 b5 b4 b3 : 0 r7 r6 r5 r4 r3 g7 g6
*/
((unsigned short *)dst)[x] =
((r & 0xF8) >> 1) |
((g & 0xC0) >> 6) |
((g & 0x38) << 10) |
((b & 0xF8) << 5);
}
src += srcstride;
dst += dststride;
}
}
 
static void
ximage_convert_bgr233(PARAMS)
{
unsigned char r, g, b;
int x,y;
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
r = src[4*x + 0];
g = src[4*x + 1];
b = src[4*x + 2];
/* format: b7 b6 g7 g6 g5 r7 r6 r5 */
dst[x] = (b&0xC0) | ((g>>2)&0x38) | ((r>>5)&0x7);
}
src += srcstride;
dst += dststride;
}
}
 
ximage_convert_func_t ximage_convert_funcs[] = {
ximage_convert_argb8888,
ximage_convert_bgra8888,
ximage_convert_rgba8888,
ximage_convert_abgr8888,
ximage_convert_rgb888,
ximage_convert_bgr888,
ximage_convert_rgb565,
ximage_convert_rgb565_br,
ximage_convert_rgb555,
ximage_convert_rgb555_br,
ximage_convert_bgr233,
};
/contrib/media/updf/apps/x11_main.c
0,0 → 1,629
#include "fitz.h"
#include "mupdf.h"
#include "muxps.h"
#include "pdfapp.h"
 
#include <menuet/os.h>
 
// #include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
 
 
 
#ifndef timeradd
#define timeradd(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
if ((result)->tv_usec >= 1000000) \
{ \
++(result)->tv_sec; \
(result)->tv_usec -= 1000000; \
} \
} while (0)
#endif
 
#ifndef timersub
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
 
extern int ximage_init(Display *display, int screen, Visual *visual);
extern int ximage_get_depth(void);
extern Visual *ximage_get_visual(void);
extern Colormap ximage_get_colormap(void);
extern void ximage_blit(Drawable d, GC gc, int dstx, int dsty,
unsigned char *srcdata,
int srcx, int srcy, int srcw, int srch, int srcstride);
 
static Display *xdpy;
static Atom XA_TARGETS;
static Atom XA_TIMESTAMP;
static Atom XA_UTF8_STRING;
static Atom WM_DELETE_WINDOW;
static int x11fd;
static int xscr;
static Window xwin;
static Pixmap xicon, xmask;
static GC xgc;
static XEvent xevt;
static int mapped = 0;
static Cursor xcarrow, xchand, xcwait;
static int justcopied = 0;
static int dirty = 0;
static int dirtysearch = 0;
static char *password = "";
static XColor xbgcolor;
static XColor xshcolor;
static int reqw = 0;
static int reqh = 0;
static char copylatin1[1024 * 16] = "";
static char copyutf8[1024 * 48] = "";
static Time copytime;
static char *filename;
 
static pdfapp_t gapp;
static int closing = 0;
static int reloading = 0;
 
/*
* Dialog boxes
*/
 
void winwarn(pdfapp_t *app, char *msg)
{
fprintf(stderr, "mupdf: %s\n", msg);
}
 
void winerror(pdfapp_t *app, fz_error error)
{
fz_catch(error, "aborting");
exit(1);
}
 
char *winpassword(pdfapp_t *app, char *filename)
{
char *r = password;
password = NULL;
return r;
}
 
/*
* X11 magic
*/
 
static void winopen(void)
{
 
/*
xwin = XCreateWindow(xdpy, DefaultRootWindow(xdpy),
10, 10, 200, 100, 1,
ximage_get_depth(),
InputOutput,
ximage_get_visual(),
0,
NULL); */
__menuet__define_window(10,10,200,200,
0,0,0);
}
 
void winclose(pdfapp_t *app)
{
closing = 1;
}
 
void wincursor(pdfapp_t *app, int curs)
{
}
 
void wintitle(pdfapp_t *app, char *s)
{
}
 
void winhelp(pdfapp_t *app)
{
}
 
void winresize(pdfapp_t *app, int w, int h)
{
 
}
 
static void fillrect(int x, int y, int w, int h)
{
if (w > 0 && h > 0)
XFillRectangle(xdpy, xwin, xgc, x, y, w, h);
}
 
static void winblitsearch(pdfapp_t *app)
{
if (gapp.isediting)
{
char buf[sizeof(gapp.search) + 50];
sprintf(buf, "Search: %s", gapp.search);
XSetForeground(xdpy, xgc, WhitePixel(xdpy, xscr));
fillrect(0, 0, gapp.winw, 30);
windrawstring(&gapp, 10, 20, buf);
}
}
 
static void winblit(pdfapp_t *app)
{
int x0 = gapp.panx;
int y0 = gapp.pany;
int x1 = gapp.panx + gapp.image->w;
int y1 = gapp.pany + gapp.image->h;
 
XSetForeground(xdpy, xgc, xbgcolor.pixel);
fillrect(0, 0, x0, gapp.winh);
fillrect(x1, 0, gapp.winw - x1, gapp.winh);
fillrect(0, 0, gapp.winw, y0);
fillrect(0, y1, gapp.winw, gapp.winh - y1);
 
XSetForeground(xdpy, xgc, xshcolor.pixel);
fillrect(x0+2, y1, gapp.image->w, 2);
fillrect(x1, y0+2, 2, gapp.image->h);
 
if (gapp.iscopying || justcopied)
{
pdfapp_invert(&gapp, gapp.selr);
justcopied = 1;
}
 
pdfapp_inverthit(&gapp);
 
if (gapp.image->n == 4)
ximage_blit(xwin, xgc,
x0, y0,
gapp.image->samples,
0, 0,
gapp.image->w,
gapp.image->h,
gapp.image->w * gapp.image->n);
else if (gapp.image->n == 2)
{
int i = gapp.image->w*gapp.image->h;
unsigned char *color = malloc(i*4);
if (color != NULL)
{
unsigned char *s = gapp.image->samples;
unsigned char *d = color;
for (; i > 0 ; i--)
{
d[2] = d[1] = d[0] = *s++;
d[3] = *s++;
d += 4;
}
ximage_blit(xwin, xgc,
x0, y0,
color,
0, 0,
gapp.image->w,
gapp.image->h,
gapp.image->w * 4);
free(color);
}
}
 
pdfapp_inverthit(&gapp);
 
if (gapp.iscopying || justcopied)
{
pdfapp_invert(&gapp, gapp.selr);
justcopied = 1;
}
 
winblitsearch(app);
}
 
void winrepaint(pdfapp_t *app)
{
dirty = 1;
}
 
void winrepaintsearch(pdfapp_t *app)
{
dirtysearch = 1;
}
 
void windrawstringxor(pdfapp_t *app, int x, int y, char *s)
{
int prevfunction;
XGCValues xgcv;
 
XGetGCValues(xdpy, xgc, GCFunction, &xgcv);
prevfunction = xgcv.function;
xgcv.function = GXxor;
XChangeGC(xdpy, xgc, GCFunction, &xgcv);
 
XSetForeground(xdpy, xgc, WhitePixel(xdpy, DefaultScreen(xdpy)));
 
XDrawString(xdpy, xwin, xgc, x, y, s, strlen(s));
XFlush(xdpy);
 
XGetGCValues(xdpy, xgc, GCFunction, &xgcv);
xgcv.function = prevfunction;
XChangeGC(xdpy, xgc, GCFunction, &xgcv);
 
printf("drawstring '%s'\n", s);
}
 
void windrawstring(pdfapp_t *app, int x, int y, char *s)
{
XSetForeground(xdpy, xgc, BlackPixel(xdpy, DefaultScreen(xdpy)));
XDrawString(xdpy, xwin, xgc, x, y, s, strlen(s));
}
 
void windocopy(pdfapp_t *app)
{
/* unsigned short copyucs2[16 * 1024];
char *latin1 = copylatin1;
char *utf8 = copyutf8;
unsigned short *ucs2;
int ucs;
 
pdfapp_oncopy(&gapp, copyucs2, 16 * 1024);
 
for (ucs2 = copyucs2; ucs2[0] != 0; ucs2++)
{
ucs = ucs2[0];
 
utf8 += runetochar(utf8, &ucs);
 
if (ucs < 256)
*latin1++ = ucs;
else
*latin1++ = '?';
}
 
*utf8 = 0;
*latin1 = 0;
 
XSetSelectionOwner(xdpy, XA_PRIMARY, xwin, copytime);
 
justcopied = 1;*/
}
 
void onselreq(Window requestor, Atom selection, Atom target, Atom property, Time time)
{
/* XEvent nevt;
 
if (property == None)
property = target;
 
nevt.xselection.type = SelectionNotify;
nevt.xselection.send_event = True;
nevt.xselection.display = xdpy;
nevt.xselection.requestor = requestor;
nevt.xselection.selection = selection;
nevt.xselection.target = target;
nevt.xselection.property = property;
nevt.xselection.time = time;
 
if (target == XA_TARGETS)
{
Atom atomlist[4];
atomlist[0] = XA_TARGETS;
atomlist[1] = XA_TIMESTAMP;
atomlist[2] = XA_STRING;
atomlist[3] = XA_UTF8_STRING;
printf(" -> targets\n");
XChangeProperty(xdpy, requestor, property, target,
32, PropModeReplace,
(unsigned char *)atomlist, sizeof(atomlist)/sizeof(Atom));
}
 
else if (target == XA_STRING)
{
XChangeProperty(xdpy, requestor, property, target,
8, PropModeReplace,
(unsigned char *)copylatin1, strlen(copylatin1));
}
 
else if (target == XA_UTF8_STRING)
{
XChangeProperty(xdpy, requestor, property, target,
8, PropModeReplace,
(unsigned char *)copyutf8, strlen(copyutf8));
}
 
else
{
nevt.xselection.property = None;
}
 
XSendEvent(xdpy, requestor, False, SelectionNotify, &nevt);
* */
}
 
void winreloadfile(pdfapp_t *app)
{
int fd;
 
pdfapp_close(app);
 
fd = open(filename, O_BINARY | O_RDONLY, 0666);
if (fd < 0)
winerror(app, fz_throw("cannot reload file '%s'", filename));
 
pdfapp_open(app, filename, fd, 1);
}
 
void winopenuri(pdfapp_t *app, char *buf)
{
/*
char *browser = getenv("BROWSER");
if (!browser)
browser = "open";
if (fork() == 0)
execlp(browser, browser, buf, (char*)0);
* */
}
 
static void onkey(int c)
{
/* if (justcopied)
{
justcopied = 0;
winrepaint(&gapp);
}
* */
 
pdfapp_onkey(&gapp, c);
}
 
static void onmouse(int x, int y, int btn, int modifiers, int state)
{
/* if (state != 0 && justcopied)
{
justcopied = 0;
winrepaint(&gapp);
}*/
 
pdfapp_onmouse(&gapp, x, y, btn, modifiers, state);
}
 
static void signal_handler(int signal)
{
/*
if (signal == SIGHUP)
reloading = 1;
* */
}
 
static void usage(void)
{
fprintf(stderr, "usage: mupdf [options] file.pdf [page]\n");
fprintf(stderr, "\t-b -\tset anti-aliasing quality in bits (0=off, 8=best)\n");
fprintf(stderr, "\t-p -\tpassword\n");
fprintf(stderr, "\t-r -\tresolution\n");
fprintf(stderr, "\t-A\tdisable accelerated functions\n");
exit(1);
}
 
int main(int argc, char **argv)
{
int c;
int len;
char buf[128];
KeySym keysym;
int oldx = 0;
int oldy = 0;
int resolution = 72;
int pageno = 1;
int accelerate = 1;
int fd;
fd_set fds;
int width = -1;
int height = -1;
 
while ((c = fz_getopt(argc, argv, "p:r:b:A")) != -1)
{
switch (c)
{
case 'p': password = fz_optarg; break;
case 'r': resolution = atoi(fz_optarg); break;
case 'A': accelerate = 0; break;
case 'b': fz_set_aa_level(atoi(fz_optarg)); break;
default: usage();
}
}
 
if (resolution < MINRES)
resolution = MINRES;
if (resolution > MAXRES)
resolution = MAXRES;
 
if (argc - fz_optind == 0)
usage();
 
filename = argv[fz_optind++];
 
if (argc - fz_optind == 1)
pageno = atoi(argv[fz_optind++]);
 
if (accelerate)
fz_accelerate();
 
winopen();
 
pdfapp_init(&gapp);
gapp.scrw = DisplayWidth(xdpy, xscr);
gapp.scrh = DisplayHeight(xdpy, xscr);
gapp.resolution = resolution;
gapp.pageno = pageno;
 
fd = open(filename, O_BINARY | O_RDONLY, 0666);
if (fd < 0)
winerror(&gapp, fz_throw("cannot open file '%s'", filename));
 
pdfapp_open(&gapp, filename, fd, 0);
 
FD_ZERO(&fds);
FD_SET(x11fd, &fds);
 
signal(SIGHUP, signal_handler);
 
while (!closing)
{
do
{
XNextEvent(xdpy, &xevt);
 
switch (xevt.type)
{
case Expose:
dirty = 1;
break;
 
case ConfigureNotify:
if (gapp.image)
{
if (xevt.xconfigure.width != reqw ||
xevt.xconfigure.height != reqh)
gapp.shrinkwrap = 0;
}
width = xevt.xconfigure.width;
height = xevt.xconfigure.height;
 
break;
 
case KeyPress:
len = XLookupString(&xevt.xkey, buf, sizeof buf, &keysym, NULL);
 
if (!gapp.isediting)
switch (keysym)
{
case XK_Escape:
len = 1; buf[0] = '\033';
break;
 
case XK_Up:
len = 1; buf[0] = 'k';
break;
case XK_Down:
len = 1; buf[0] = 'j';
break;
 
case XK_Left:
len = 1; buf[0] = 'b';
break;
case XK_Right:
len = 1; buf[0] = ' ';
break;
 
case XK_Page_Up:
len = 1; buf[0] = ',';
break;
case XK_Page_Down:
len = 1; buf[0] = '.';
break;
}
if (len)
onkey(buf[0]);
 
onmouse(oldx, oldy, 0, 0, 0);
 
break;
 
case MotionNotify:
oldx = xevt.xbutton.x;
oldy = xevt.xbutton.y;
onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 0);
break;
 
case ButtonPress:
onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, 1);
break;
 
case ButtonRelease:
copytime = xevt.xbutton.time;
onmouse(xevt.xbutton.x, xevt.xbutton.y, xevt.xbutton.button, xevt.xbutton.state, -1);
break;
 
case SelectionRequest:
onselreq(xevt.xselectionrequest.requestor,
xevt.xselectionrequest.selection,
xevt.xselectionrequest.target,
xevt.xselectionrequest.property,
xevt.xselectionrequest.time);
break;
 
case ClientMessage:
if (xevt.xclient.format == 32 && xevt.xclient.data.l[0] == WM_DELETE_WINDOW)
closing = 1;
break;
}
}
while (!closing && XPending(xdpy));
 
if (closing)
continue;
 
if (width != -1 || height != -1)
{
pdfapp_onresize(&gapp, width, height);
width = -1;
height = -1;
}
 
if (dirty || dirtysearch)
{
if (dirty)
winblit(&gapp);
else if (dirtysearch)
winblitsearch(&gapp);
dirty = 0;
dirtysearch = 0;
}
 
if (XPending(xdpy))
continue;
 
if (select(x11fd + 1, &fds, NULL, NULL, NULL) < 0)
{
if (reloading)
{
winreloadfile(&gapp);
reloading = 0;
}
}
}
 
pdfapp_close(&gapp);
 
XDestroyWindow(xdpy, xwin);
 
XFreePixmap(xdpy, xicon);
 
XFreeCursor(xdpy, xcwait);
XFreeCursor(xdpy, xchand);
XFreeCursor(xdpy, xcarrow);
 
XFreeGC(xdpy, xgc);
 
XCloseDisplay(xdpy);
 
return 0;
}