1 /* mview.c -- File viewer -*- coding: euc-jp; -*-
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @enpage m17n-view view file
26 @section m17n-view-synopsis SYNOPSIS
28 m17n-view [ XT-OPTION ...] [ OPTION ... ] [ FILE ]
30 @section m17n-view-description DESCRIPTION
32 Display FILE on a window.
34 If FILE is omitted, the input is taken from standard input.
36 XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg).
38 The following OPTIONs are available.
44 ENCODING is the encoding of FILE (defaults to UTF-8).
48 FONTSIZE is the fontsize in point. If ommited, it defaults to the
49 size of the default font defined in X resource.
62 @japage m17n-view ¥Õ¥¡¥¤¥ë¤ò¸«¤ë
64 @section m17n-view-synopsis SYNOPSIS
66 m17n-view [ XT-OPTION ...] [ OPTION ... ] [ FILE ]
68 @section m17n-view-description DESCRIPTION
70 FILE ¤ò¥¦¥£¥ó¥É¥¦¤Ëɽ¼¨¤¹¤ë¡£
72 FILE ¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Ï¡¢É¸½àÆþÎϤ«¤é¤È¤ë¡£
74 XT-OPTIONs ¤Ï Xt ¤Îɸ½à¤Î°ú¿ô¤Ç¤¢¤ë¡£ (e.g. -fn, -fg).
76 °Ê²¼¤Î¥ª¥×¥·¥ç¥ó¤¬ÍøÍѤǤ¤ë¡£
82 ENCODING ¤Ï FILE ¤Î¥³¡¼¥É·Ï¤Ç¤¢¤ë¡£(¥Ç¥Õ¥©¥ë¥È¤Ï UTF-8)
86 FONTSIZE ¤Ï¥Õ¥©¥ó¥È¤ÎÂ礤µ¤ò¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¾Êά
87 ¤µ¤ì¤¿¾ì¹ç¤Ï¡¢X ¤Î¥ê¥½¡¼¥¹¤ÇÄêµÁ¤µ¤ì¤¿¥Ç¥Õ¥©¥ë¥È¥Õ¥©¥ó¥È¤ÎÂ礤µ¤È
92 ¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤òɽ¼¨¤¹¤ë¡£
96 ¤³¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤¹¤ë¡£
104 #include <X11/Intrinsic.h>
105 #include <X11/StringDefs.h>
106 #include <X11/Shell.h>
107 #include <X11/Xaw/Form.h>
108 #include <X11/Xaw/Command.h>
109 #include <X11/Xaw/Viewport.h>
111 #include <m17n-gui.h>
112 #include <m17n-misc.h>
115 #define VERSION "1.2.0"
117 /* Global m17n variables. */
121 MDrawControl control;
124 /* Callback procedure for "quit". */
127 QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
129 XtAppSetExitFlag (XtWidgetToApplicationContext (w));
133 /* Move POS to the next line head in M-text MT whose length is LEN.
134 If POS is already on the last line, set POS to LEN. */
136 #define NEXTLINE(pos, len) \
138 pos = mtext_character (mt, pos, len, '\n'); \
146 /* Action procedure for expose event. Redraw partial area of the
147 widget W. The area is specified in EVENT. */
150 ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num)
152 XExposeEvent *expose = (XExposeEvent *) event;
153 int len = mtext_len (mt);
158 /* We must update the area between the Y-positions expose->y and
159 (expose->y + expose->height). We ignore X-positions. */
161 /* At first, find the line that occupies the Y-position expose->y.
162 That is the first line to draw. */
168 mdraw_text_extents (frame, mt, from, to, &control, NULL, NULL, &rect);
169 if (to == len || y + rect.height > expose->y)
173 /* The first character to draw is at position FROM. Remeber the
174 Y-position to start drawing. */
177 /* Next, find the line that occupies the Y-position (expose->y +
178 expose->height). That is the last line to draw. This time, we
179 enable caching to utilize it in the later drawing. */
181 control.disable_caching = 0;
182 while (to < len && y < expose->y + expose->height)
186 mdraw_text_extents (frame, mt, pos, to, &control, NULL, NULL, &rect);
190 /* It is decided that we must draw from FROM to the previous
192 mdraw_text_with_control (frame, (MDrawWindow) XtWindow (w),
193 0, yoff, mt, from, to, &control);
195 /* Disable caching again. */
196 control.disable_caching = 1;
198 /* If the widget was vertically enlarged too much, shrink it. */
199 if (metric.height < expose->y + expose->height)
203 XtSetArg (arg, XtNheight, metric.height);
204 XtSetValues (w, &arg, 0);
209 /* Print the usage of this program (the name is PROG), and exit with
213 help_exit (char *prog, int exit_code)
221 printf ("Usage: %s [ XT-OPTION ...] [ OPTION ...] [ FILE ]\n", prog);
222 printf ("Display FILE on a window.\n");
223 printf (" If FILE is omitted, the input is taken from standard input.\n");
224 printf (" XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg).\n");
225 printf ("The following OPTIONs are available.\n");
226 printf (" %-13s %s", "-e ENCODING",
227 "ENCODING is the encoding of FILE (defaults to UTF-8).\n");
228 printf (" %-13s %s", "-s FONTSIZE",
229 "FONTSIZE is the fontsize in point.\n");
230 printf ("\t\tIf ommited, it defaults to the size\n");
231 printf ("\t\tof the default font defined in X resource.\n");
232 printf (" %-13s %s", "--version", "print version number\n");
233 printf (" %-13s %s", "-h, --help", "print this message\n");
238 /* Format MSG by FMT and print the result to the stderr, and exit. */
240 #define FATAL_ERROR(fmt, arg) \
242 fprintf (stderr, fmt, arg); \
247 /* Adjust FONTSIZE for the resolution of the screen of widget W. */
250 adjust_fontsize (Widget w, int fontsize)
252 Display *display = XtDisplay (w);
253 int screen_number = XScreenNumberOfScreen (XtScreen (w));
254 double pixels = DisplayHeight (display, screen_number);
255 double mm = DisplayHeightMM (display, screen_number);
257 return (fontsize * pixels * 25.4 / mm / 100);
262 main (int argc, char **argv)
264 XtAppContext context;
265 Widget shell, form, quit, viewport, text;
266 String quit_action = "<KeyPress>q: set() notify() unset()";
267 XtActionsRec actions[] = { {"Expose", ExposeProc} };
270 int viewport_width, viewport_height;
271 char *coding_name = NULL;
276 /* Open an application context. */
277 XtSetLanguageProc (NULL, NULL, NULL);
278 shell = XtOpenApplication (&context, "M17NView", NULL, 0, &argc, argv, NULL,
279 sessionShellWidgetClass, NULL, 0);
280 XtAppAddActions (context, actions, XtNumber (actions));
282 /* Parse the remaining command line arguments. */
283 for (i = 1; i < argc; i++)
285 if (! strcmp (argv[i], "--help")
286 || ! strcmp (argv[i], "-h"))
287 help_exit (argv[0], 0);
288 else if (! strcmp (argv[i], "--version"))
290 printf ("m17n-view (m17n library) %s\n", VERSION);
291 printf ("Copyright (C) 2003 AIST, JAPAN\n");
294 else if (! strcmp (argv[i], "-e"))
297 coding_name = argv[i];
299 else if (! strcmp (argv[i], "-s"))
305 FATAL_ERROR ("Invalid fontsize %s!\n", argv[i]);
306 fontsize = adjust_fontsize (shell, (int) (n * 10));
308 else if (argv[i][0] != '-')
310 fp = fopen (argv[i], "r");
312 FATAL_ERROR ("Fail to open the file %s!\n", argv[i]);
316 printf ("Unknown option: %s", argv[i]);
317 help_exit (argv[0], 1);
321 /* Initialize the m17n library. */
323 if (merror_code != MERROR_NONE)
324 FATAL_ERROR ("%s\n", "Fail to initialize the m17n library.");
326 /* Decide how to decode the input stream. */
329 coding = mconv_resolve_coding (msymbol (coding_name));
331 FATAL_ERROR ("Invalid coding: %s\n", coding_name);
334 coding = Mcoding_utf_8;
336 mt = mconv_decode_stream (coding, fp);
339 FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!");
342 MPlist *param = mplist ();
343 MFace *face = mface ();
346 mface_put_prop (face, Msize, (void *) fontsize);
347 mplist_put (param, Mwidget, shell);
348 mplist_put (param, Mface, face);
349 frame = mframe (param);
350 m17n_object_unref (param);
351 m17n_object_unref (face);
354 /* Create this widget hierarchy.
355 Shell - form -+- quit
357 +- viewport - text */
359 form = XtCreateManagedWidget ("form", formWidgetClass, shell, NULL, 0);
360 XtSetArg (arg[0], XtNleft, XawChainLeft);
361 XtSetArg (arg[1], XtNright, XawChainLeft);
362 XtSetArg (arg[2], XtNtop, XawChainTop);
363 XtSetArg (arg[3], XtNbottom, XawChainTop);
364 XtSetArg (arg[4], XtNaccelerators, XtParseAcceleratorTable (quit_action));
365 quit = XtCreateManagedWidget ("quit", commandWidgetClass, form, arg, 5);
366 XtAddCallback (quit, XtNcallback, QuitProc, NULL);
368 viewport_width = (int) mframe_get_prop (frame, Mfont_width) * 80;
370 = ((int) mframe_get_prop (frame, Mfont_ascent)
371 + (int) mframe_get_prop (frame, Mfont_descent)) * 24;
372 XtSetArg (arg[0], XtNallowVert, True);
373 XtSetArg (arg[1], XtNforceBars, False);
374 XtSetArg (arg[2], XtNfromVert, quit);
375 XtSetArg (arg[3], XtNtop, XawChainTop);
376 XtSetArg (arg[4], XtNbottom, XawChainBottom);
377 XtSetArg (arg[5], XtNright, XawChainRight);
378 XtSetArg (arg[6], XtNwidth, viewport_width);
379 XtSetArg (arg[7], XtNheight, viewport_height);
380 viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, form,
383 /* Before creating the text widget, we must calculate the height of
384 the M-text to draw. */
385 control.two_dimensional = 1;
386 control.enable_bidi = 1;
387 control.disable_caching = 1;
388 control.max_line_width = viewport_width;
389 mdraw_text_extents (frame, mt, 0, mtext_len (mt), &control,
390 NULL, NULL, &metric);
393 /* Decide the size of the text widget. */
394 XtSetArg (arg[0], XtNwidth, viewport_width);
395 if (viewport_height > metric.height)
396 /* The outer viewport is tall enough. */
397 XtSetArg (arg[1], XtNheight, viewport_height);
398 else if (metric.height < 0x8000)
399 /* The M-text height is within the limit of X. */
400 XtSetArg (arg[1], XtNheight, metric.height);
402 /* We can't make such a tall widget. Truncate it. */
403 XtSetArg (arg[1], XtNheight, 0x7FFF);
405 /* We must provide our own expose event handler. */
406 XtSetArg (arg[2], XtNtranslations,
407 XtParseTranslationTable ((String) "<Expose>: Expose()"));
408 text = XtCreateManagedWidget ("text", simpleWidgetClass, viewport, arg, 3);
411 /* Realize the top widget, and dive into an even loop. */
412 XtInstallAllAccelerators (form, form);
413 XtRealizeWidget (shell);
414 XtAppMainLoop (context);
417 m17n_object_unref (mt);
418 m17n_object_unref (frame);
423 #endif /* not FOR_DOXYGEN */