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>
108 #include <m17n-gui.h>
109 #include <m17n-misc.h>
114 #ifdef HAVE_X11_XAW_COMMAND_H
116 #include <X11/Xaw/Form.h>
117 #include <X11/Xaw/Command.h>
118 #include <X11/Xaw/Viewport.h>
120 #define VERSION "1.2.0"
122 /* Global m17n variables. */
126 MDrawControl control;
129 /* Callback procedure for "quit". */
132 QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
134 XtAppSetExitFlag (XtWidgetToApplicationContext (w));
138 /* Move POS to the next line head in M-text MT whose length is LEN.
139 If POS is already on the last line, set POS to LEN. */
141 #define NEXTLINE(pos, len) \
143 pos = mtext_character (mt, pos, len, '\n'); \
151 /* Action procedure for expose event. Redraw partial area of the
152 widget W. The area is specified in EVENT. */
155 ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num)
157 XExposeEvent *expose = (XExposeEvent *) event;
158 int len = mtext_len (mt);
163 /* We must update the area between the Y-positions expose->y and
164 (expose->y + expose->height). We ignore X-positions. */
166 /* At first, find the line that occupies the Y-position expose->y.
167 That is the first line to draw. */
173 mdraw_text_extents (frame, mt, from, to, &control, NULL, NULL, &rect);
174 if (to == len || y + rect.height > expose->y)
178 /* The first character to draw is at position FROM. Remeber the
179 Y-position to start drawing. */
182 /* Next, find the line that occupies the Y-position (expose->y +
183 expose->height). That is the last line to draw. This time, we
184 enable caching to utilize it in the later drawing. */
186 control.disable_caching = 0;
187 while (to < len && y < expose->y + expose->height)
191 mdraw_text_extents (frame, mt, pos, to, &control, NULL, NULL, &rect);
195 /* It is decided that we must draw from FROM to the previous
197 mdraw_text_with_control (frame, (MDrawWindow) XtWindow (w),
198 0, yoff, mt, from, to, &control);
200 /* Disable caching again. */
201 control.disable_caching = 1;
203 /* If the widget was vertically enlarged too much, shrink it. */
204 if (metric.height < expose->y + expose->height)
208 XtSetArg (arg, XtNheight, metric.height);
209 XtSetValues (w, &arg, 0);
214 /* Print the usage of this program (the name is PROG), and exit with
218 help_exit (char *prog, int exit_code)
226 printf ("Usage: %s [ XT-OPTION ...] [ OPTION ...] [ FILE ]\n", prog);
227 printf ("Display FILE on a window.\n");
228 printf (" If FILE is omitted, the input is taken from standard input.\n");
229 printf (" XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg).\n");
230 printf ("The following OPTIONs are available.\n");
231 printf (" %-13s %s", "-e ENCODING",
232 "ENCODING is the encoding of FILE (defaults to UTF-8).\n");
233 printf (" %-13s %s", "-s FONTSIZE",
234 "FONTSIZE is the fontsize in point.\n");
235 printf ("\t\tIf ommited, it defaults to the size\n");
236 printf ("\t\tof the default font defined in X resource.\n");
237 printf (" %-13s %s", "--version", "print version number\n");
238 printf (" %-13s %s", "-h, --help", "print this message\n");
243 /* Format MSG by FMT and print the result to the stderr, and exit. */
245 #define FATAL_ERROR(fmt, arg) \
247 fprintf (stderr, fmt, arg); \
252 /* Adjust FONTSIZE for the resolution of the screen of widget W. */
255 adjust_fontsize (Widget w, int fontsize)
257 Display *display = XtDisplay (w);
258 int screen_number = XScreenNumberOfScreen (XtScreen (w));
259 double pixels = DisplayHeight (display, screen_number);
260 double mm = DisplayHeightMM (display, screen_number);
262 return (fontsize * pixels * 25.4 / mm / 100);
267 main (int argc, char **argv)
269 XtAppContext context;
270 Widget shell, form, quit, viewport, text;
271 String quit_action = "<KeyPress>q: set() notify() unset()";
272 XtActionsRec actions[] = { {"Expose", ExposeProc} };
275 int viewport_width, viewport_height;
276 char *coding_name = NULL;
281 /* Open an application context. */
282 XtSetLanguageProc (NULL, NULL, NULL);
283 shell = XtOpenApplication (&context, "M17NView", NULL, 0, &argc, argv, NULL,
284 sessionShellWidgetClass, NULL, 0);
285 XtAppAddActions (context, actions, XtNumber (actions));
287 /* Parse the remaining command line arguments. */
288 for (i = 1; i < argc; i++)
290 if (! strcmp (argv[i], "--help")
291 || ! strcmp (argv[i], "-h"))
292 help_exit (argv[0], 0);
293 else if (! strcmp (argv[i], "--version"))
295 printf ("m17n-view (m17n library) %s\n", VERSION);
296 printf ("Copyright (C) 2003 AIST, JAPAN\n");
299 else if (! strcmp (argv[i], "-e"))
302 coding_name = argv[i];
304 else if (! strcmp (argv[i], "-s"))
310 FATAL_ERROR ("Invalid fontsize %s!\n", argv[i]);
311 fontsize = adjust_fontsize (shell, (int) (n * 10));
313 else if (argv[i][0] != '-')
315 fp = fopen (argv[i], "r");
317 FATAL_ERROR ("Fail to open the file %s!\n", argv[i]);
321 printf ("Unknown option: %s", argv[i]);
322 help_exit (argv[0], 1);
326 /* Initialize the m17n library. */
328 if (merror_code != MERROR_NONE)
329 FATAL_ERROR ("%s\n", "Fail to initialize the m17n library.");
331 /* Decide how to decode the input stream. */
334 coding = mconv_resolve_coding (msymbol (coding_name));
336 FATAL_ERROR ("Invalid coding: %s\n", coding_name);
339 coding = Mcoding_utf_8;
341 mt = mconv_decode_stream (coding, fp);
344 FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!");
347 MPlist *param = mplist ();
348 MFace *face = mface ();
351 mface_put_prop (face, Msize, (void *) fontsize);
352 mplist_put (param, Mwidget, shell);
353 mplist_put (param, Mface, face);
354 frame = mframe (param);
355 m17n_object_unref (param);
356 m17n_object_unref (face);
359 /* Create this widget hierarchy.
360 Shell - form -+- quit
362 +- viewport - text */
364 form = XtCreateManagedWidget ("form", formWidgetClass, shell, NULL, 0);
365 XtSetArg (arg[0], XtNleft, XawChainLeft);
366 XtSetArg (arg[1], XtNright, XawChainLeft);
367 XtSetArg (arg[2], XtNtop, XawChainTop);
368 XtSetArg (arg[3], XtNbottom, XawChainTop);
369 XtSetArg (arg[4], XtNaccelerators, XtParseAcceleratorTable (quit_action));
370 quit = XtCreateManagedWidget ("quit", commandWidgetClass, form, arg, 5);
371 XtAddCallback (quit, XtNcallback, QuitProc, NULL);
373 viewport_width = (int) mframe_get_prop (frame, Mfont_width) * 80;
375 = ((int) mframe_get_prop (frame, Mfont_ascent)
376 + (int) mframe_get_prop (frame, Mfont_descent)) * 24;
377 XtSetArg (arg[0], XtNallowVert, True);
378 XtSetArg (arg[1], XtNforceBars, False);
379 XtSetArg (arg[2], XtNfromVert, quit);
380 XtSetArg (arg[3], XtNtop, XawChainTop);
381 XtSetArg (arg[4], XtNbottom, XawChainBottom);
382 XtSetArg (arg[5], XtNright, XawChainRight);
383 XtSetArg (arg[6], XtNwidth, viewport_width);
384 XtSetArg (arg[7], XtNheight, viewport_height);
385 viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, form,
388 /* Before creating the text widget, we must calculate the height of
389 the M-text to draw. */
390 control.two_dimensional = 1;
391 control.enable_bidi = 1;
392 control.disable_caching = 1;
393 control.max_line_width = viewport_width;
394 mdraw_text_extents (frame, mt, 0, mtext_len (mt), &control,
395 NULL, NULL, &metric);
398 /* Decide the size of the text widget. */
399 XtSetArg (arg[0], XtNwidth, viewport_width);
400 if (viewport_height > metric.height)
401 /* The outer viewport is tall enough. */
402 XtSetArg (arg[1], XtNheight, viewport_height);
403 else if (metric.height < 0x8000)
404 /* The M-text height is within the limit of X. */
405 XtSetArg (arg[1], XtNheight, metric.height);
407 /* We can't make such a tall widget. Truncate it. */
408 XtSetArg (arg[1], XtNheight, 0x7FFF);
410 /* We must provide our own expose event handler. */
411 XtSetArg (arg[2], XtNtranslations,
412 XtParseTranslationTable ((String) "<Expose>: Expose()"));
413 text = XtCreateManagedWidget ("text", simpleWidgetClass, viewport, arg, 3);
416 /* Realize the top widget, and dive into an even loop. */
417 XtInstallAllAccelerators (form, form);
418 XtRealizeWidget (shell);
419 XtAppMainLoop (context);
422 m17n_object_unref (mt);
423 m17n_object_unref (frame);
429 #else /* not HAVE_X11_XAW_COMMAND_H */
432 main (int argc, char **argv)
435 "Building of this program failed (lack of some header files)\n");
439 #endif /* not HAVE_X11_XAW_COMMAND_H */
441 #endif /* not FOR_DOXYGEN */