1 /* mview.c -- File viewer -*- coding: euc-jp; -*-
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
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., 51 Franklin Street, Fifth Floor,
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 omitted, 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 ¤³¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤¹¤ë¡£
105 #ifdef HAVE_X11_XAW_COMMAND_H
107 #include <X11/Intrinsic.h>
108 #include <X11/StringDefs.h>
109 #include <X11/Shell.h>
111 #include <m17n-gui.h>
112 #include <m17n-misc.h>
115 #include <X11/Xaw/Form.h>
116 #include <X11/Xaw/Command.h>
117 #include <X11/Xaw/Viewport.h>
119 /* Global m17n variables. */
123 MDrawControl control;
126 /* Callback procedure for "quit". */
129 QuitProc (Widget w, XtPointer client_data, XtPointer call_data)
131 XtAppSetExitFlag (XtWidgetToApplicationContext (w));
135 /* Move POS to the next line head in M-text MT whose length is LEN.
136 If POS is already on the last line, set POS to LEN. */
138 #define NEXTLINE(pos, len) \
140 pos = mtext_character (mt, pos, len, '\n'); \
148 /* Action procedure for expose event. Redraw partial area of the
149 widget W. The area is specified in EVENT. */
152 ExposeProc (Widget w, XEvent *event, String *str, Cardinal *num)
154 XExposeEvent *expose = (XExposeEvent *) event;
155 int len = mtext_len (mt);
160 /* We must update the area between the Y-positions expose->y and
161 (expose->y + expose->height). We ignore X-positions. */
163 /* At first, find the line that occupies the Y-position expose->y.
164 That is the first line to draw. */
170 mdraw_text_extents (frame, mt, from, to, &control, NULL, NULL, &rect);
171 if (to == len || y + rect.height > expose->y)
175 /* The first character to draw is at position FROM. Remeber the
176 Y-position to start drawing. */
179 /* Next, find the line that occupies the Y-position (expose->y +
180 expose->height). That is the last line to draw. This time, we
181 enable caching to utilize it in the later drawing. */
183 control.disable_caching = 0;
184 while (to < len && y < expose->y + expose->height)
188 mdraw_text_extents (frame, mt, pos, to, &control, NULL, NULL, &rect);
192 /* It is decided that we must draw from FROM to the previous
194 mdraw_text_with_control (frame, (MDrawWindow) XtWindow (w),
195 0, yoff, mt, from, to, &control);
197 /* Disable caching again. */
198 control.disable_caching = 1;
200 /* If the widget was vertically enlarged too much, shrink it. */
201 if (metric.height < expose->y + expose->height)
205 XtSetArg (arg, XtNheight, metric.height);
206 XtSetValues (w, &arg, 0);
211 /* Print the usage of this program (the name is PROG), and exit with
215 help_exit (char *prog, int exit_code)
223 printf ("Usage: %s [ XT-OPTION ...] [ OPTION ...] [ FILE ]\n", prog);
224 printf ("Display FILE on a window.\n");
225 printf (" If FILE is omitted, the input is taken from standard input.\n");
226 printf (" XT-OPTIONs are standard Xt arguments (e.g. -fn, -fg).\n");
227 printf ("The following OPTIONs are available.\n");
228 printf (" %-13s %s", "-e ENCODING",
229 "ENCODING is the encoding of FILE (defaults to UTF-8).\n");
230 printf (" %-13s %s", "-s FONTSIZE",
231 "FONTSIZE is the fontsize in point.\n");
232 printf ("\t\tIf omitted, it defaults to the size\n");
233 printf ("\t\tof the default font defined in X resource.\n");
234 printf (" %-13s %s", "--version", "print version number\n");
235 printf (" %-13s %s", "-h, --help", "print this message\n");
240 /* Format MSG by FMT and print the result to the stderr, and exit. */
242 #define FATAL_ERROR(fmt, arg) \
244 fprintf (stderr, fmt, arg); \
249 /* Adjust FONTSIZE for the resolution of the screen of widget W. */
252 adjust_fontsize (Widget w, int fontsize)
254 Display *display = XtDisplay (w);
255 int screen_number = XScreenNumberOfScreen (XtScreen (w));
256 double pixels = DisplayHeight (display, screen_number);
257 double mm = DisplayHeightMM (display, screen_number);
259 return (fontsize * pixels * 25.4 / mm / 100);
264 main (int argc, char **argv)
266 XtAppContext context;
267 Widget shell, form, quit, viewport, text;
268 String quit_action = "<KeyPress>q: set() notify() unset()";
269 XtActionsRec actions[] = { {"Expose", ExposeProc} };
272 int viewport_width, viewport_height;
273 char *coding_name = NULL;
278 /* Open an application context. */
279 XtSetLanguageProc (NULL, NULL, NULL);
280 shell = XtOpenApplication (&context, "M17NView", NULL, 0, &argc, argv, NULL,
281 sessionShellWidgetClass, NULL, 0);
282 XtAppAddActions (context, actions, XtNumber (actions));
284 /* Parse the remaining command line arguments. */
285 for (i = 1; i < argc; i++)
287 if (! strcmp (argv[i], "--help")
288 || ! strcmp (argv[i], "-h"))
289 help_exit (argv[0], 0);
290 else if (! strcmp (argv[i], "--version"))
292 printf ("m17n-view (m17n library) %s\n", M17NLIB_VERSION_NAME);
293 printf ("Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 AIST, JAPAN\n");
296 else if (! strcmp (argv[i], "-e"))
299 coding_name = argv[i];
301 else if (! strcmp (argv[i], "-s"))
307 FATAL_ERROR ("Invalid fontsize %s!\n", argv[i]);
308 fontsize = adjust_fontsize (shell, (int) (n * 10));
310 else if (argv[i][0] != '-')
312 fp = fopen (argv[i], "r");
314 FATAL_ERROR ("Fail to open the file %s!\n", argv[i]);
318 printf ("Unknown option: %s", argv[i]);
319 help_exit (argv[0], 1);
323 /* Initialize the m17n library. */
325 if (merror_code != MERROR_NONE)
326 FATAL_ERROR ("%s\n", "Fail to initialize the m17n library.");
328 /* Decide how to decode the input stream. */
331 coding = mconv_resolve_coding (msymbol (coding_name));
333 FATAL_ERROR ("Invalid coding: %s\n", coding_name);
336 coding = Mcoding_utf_8;
338 mt = mconv_decode_stream (coding, fp);
341 FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!");
344 MPlist *param = mplist ();
345 MFace *face = mface ();
348 mface_put_prop (face, Msize, (void *) fontsize);
349 mplist_put (param, Mwidget, shell);
350 mplist_put (param, Mface, face);
351 frame = mframe (param);
352 m17n_object_unref (param);
353 m17n_object_unref (face);
356 /* Create this widget hierarchy.
357 Shell - form -+- quit
359 +- viewport - text */
361 form = XtCreateManagedWidget ("form", formWidgetClass, shell, NULL, 0);
362 XtSetArg (arg[0], XtNleft, XawChainLeft);
363 XtSetArg (arg[1], XtNright, XawChainLeft);
364 XtSetArg (arg[2], XtNtop, XawChainTop);
365 XtSetArg (arg[3], XtNbottom, XawChainTop);
366 XtSetArg (arg[4], XtNaccelerators, XtParseAcceleratorTable (quit_action));
367 quit = XtCreateManagedWidget ("quit", commandWidgetClass, form, arg, 5);
368 XtAddCallback (quit, XtNcallback, QuitProc, NULL);
370 viewport_width = (int) mframe_get_prop (frame, Mfont_width) * 80;
372 = ((int) mframe_get_prop (frame, Mfont_ascent)
373 + (int) mframe_get_prop (frame, Mfont_descent)) * 24;
374 XtSetArg (arg[0], XtNallowVert, True);
375 XtSetArg (arg[1], XtNforceBars, False);
376 XtSetArg (arg[2], XtNfromVert, quit);
377 XtSetArg (arg[3], XtNtop, XawChainTop);
378 XtSetArg (arg[4], XtNbottom, XawChainBottom);
379 XtSetArg (arg[5], XtNright, XawChainRight);
380 XtSetArg (arg[6], XtNwidth, viewport_width);
381 XtSetArg (arg[7], XtNheight, viewport_height);
382 viewport = XtCreateManagedWidget ("viewport", viewportWidgetClass, form,
385 /* Before creating the text widget, we must calculate the height of
386 the M-text to draw. */
387 control.two_dimensional = 1;
388 control.enable_bidi = 1;
389 control.disable_caching = 1;
390 control.max_line_width = viewport_width;
391 mdraw_text_extents (frame, mt, 0, mtext_len (mt), &control,
392 NULL, NULL, &metric);
395 /* Decide the size of the text widget. */
396 XtSetArg (arg[0], XtNwidth, viewport_width);
397 if (viewport_height > metric.height)
398 /* The outer viewport is tall enough. */
399 XtSetArg (arg[1], XtNheight, viewport_height);
400 else if (metric.height < 0x8000)
401 /* The M-text height is within the limit of X. */
402 XtSetArg (arg[1], XtNheight, metric.height);
404 /* We can't make such a tall widget. Truncate it. */
405 XtSetArg (arg[1], XtNheight, 0x7FFF);
407 /* We must provide our own expose event handler. */
408 XtSetArg (arg[2], XtNtranslations,
409 XtParseTranslationTable ((String) "<Expose>: Expose()"));
410 text = XtCreateManagedWidget ("text", simpleWidgetClass, viewport, arg, 3);
413 /* Realize the top widget, and dive into an even loop. */
414 XtInstallAllAccelerators (form, form);
415 XtRealizeWidget (shell);
416 XtAppMainLoop (context);
419 m17n_object_unref (mt);
420 m17n_object_unref (frame);
426 #else /* not HAVE_X11_XAW_COMMAND_H */
429 main (int argc, char **argv)
432 "Building of this program failed (lack of some header files)\n");
436 #endif /* not HAVE_X11_XAW_COMMAND_H */
438 #endif /* not FOR_DOXYGEN */