Commit | Line | Data |
---|---|---|
1a578e9b | 1 | /* Definitions and headers for communication on the Mac OS. |
0b5538bd | 2 | Copyright (C) 2000, 2001, 2002, 2003, 2004, |
8cabe764 | 3 | 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
1a578e9b AC |
4 | |
5 | This file is part of GNU Emacs. | |
6 | ||
7 | GNU Emacs is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
684d6f5b | 9 | the Free Software Foundation; either version 3, or (at your option) |
1a578e9b AC |
10 | any later version. |
11 | ||
12 | GNU Emacs is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GNU Emacs; see the file COPYING. If not, write to | |
4fc5845f LK |
19 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 | Boston, MA 02110-1301, USA. */ | |
1a578e9b | 21 | |
e0f712ba | 22 | /* Contributed by Andrew Choi (akochoi@mac.com). */ |
1a578e9b AC |
23 | |
24 | #ifndef EMACS_MACGUI_H | |
25 | #define EMACS_MACGUI_H | |
26 | ||
b0b2caf8 | 27 | typedef struct _XDisplay Display; /* opaque */ |
1a578e9b | 28 | |
e7474cdd | 29 | typedef Lisp_Object XrmDatabase; |
574bdd83 | 30 | |
1a578e9b | 31 | typedef unsigned long Time; |
e0f712ba | 32 | |
24972bf6 YM |
33 | #ifdef HAVE_CARBON |
34 | #undef Z | |
35 | #ifdef MAC_OSX | |
7a92caf8 | 36 | #if ! HAVE_MKTIME || BROKEN_MKTIME |
e3564461 | 37 | #undef mktime |
7a92caf8 | 38 | #endif |
e3564461 | 39 | #undef DEBUG |
e3564461 ST |
40 | #undef free |
41 | #undef malloc | |
42 | #undef realloc | |
43 | /* Macros max and min defined in lisp.h conflict with those in | |
44 | precompiled header Carbon.h. */ | |
45 | #undef max | |
46 | #undef min | |
47 | #undef init_process | |
48 | #include <Carbon/Carbon.h> | |
7a92caf8 | 49 | #if ! HAVE_MKTIME || BROKEN_MKTIME |
c3f4c690 ST |
50 | #undef mktime |
51 | #define mktime emacs_mktime | |
7a92caf8 | 52 | #endif |
e3564461 ST |
53 | #undef free |
54 | #define free unexec_free | |
55 | #undef malloc | |
56 | #define malloc unexec_malloc | |
57 | #undef realloc | |
58 | #define realloc unexec_realloc | |
59 | #undef min | |
60 | #define min(a, b) ((a) < (b) ? (a) : (b)) | |
61 | #undef max | |
62 | #define max(a, b) ((a) > (b) ? (a) : (b)) | |
63 | #undef init_process | |
64 | #define init_process emacs_init_process | |
65 | #undef INFINITY | |
24972bf6 YM |
66 | #else /* not MAC_OSX */ |
67 | #undef SIGHUP | |
68 | #define OLDP2C 1 | |
69 | #include <Carbon.h> | |
70 | #endif /* not MAC_OSX */ | |
71 | #undef Z | |
72 | #define Z (current_buffer->text->z) | |
73 | #else /* not HAVE_CARBON */ | |
f3821d29 | 74 | #include <Quickdraw.h> /* for WindowRef */ |
e3564461 | 75 | #include <QDOffscreen.h> /* for GWorldPtr */ |
2f063626 | 76 | #include <Appearance.h> /* for ThemeCursor */ |
b15325b2 | 77 | #include <Windows.h> |
2f063626 | 78 | #include <Controls.h> |
50bf7673 | 79 | #include <Gestalt.h> |
24972bf6 | 80 | #endif /* not HAVE_CARBON */ |
1a578e9b | 81 | |
b0635670 YM |
82 | /* Whether to use ATSUI (Apple Type Services for Unicode Imaging) for |
83 | text drawing. */ | |
31ce278b | 84 | #if 0 /* Don't enable by default on the emacs-unicode-2 branch. */ |
b0635670 YM |
85 | #ifndef USE_ATSUI |
86 | #ifdef MAC_OSX | |
87 | #define USE_ATSUI 1 | |
88 | #endif | |
89 | #endif | |
31ce278b | 90 | #endif |
b0635670 YM |
91 | |
92 | /* Whether to use low-level Quartz 2D (aka Core Graphics) text drawing | |
93 | in preference to ATSUI for ASCII and Latin-1 characters. */ | |
58826ef7 YM |
94 | #ifndef USE_CG_TEXT_DRAWING |
95 | #if USE_ATSUI && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 | |
96 | #define USE_CG_TEXT_DRAWING 1 | |
97 | #endif | |
98 | #endif | |
99 | ||
b0635670 YM |
100 | /* Whether to use Quartz 2D routines for drawing operations other than |
101 | texts. */ | |
58826ef7 | 102 | #ifndef USE_CG_DRAWING |
aab33444 | 103 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 |
58826ef7 YM |
104 | #define USE_CG_DRAWING 1 |
105 | #endif | |
106 | #endif | |
107 | ||
b1b415de YM |
108 | /* Whether to use the standard Font Panel floating dialog. */ |
109 | #ifndef USE_MAC_FONT_PANEL | |
110 | #if USE_ATSUI && MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 | |
111 | #define USE_MAC_FONT_PANEL 1 | |
112 | #endif | |
113 | #endif | |
114 | ||
a625bb4e YM |
115 | /* Whether to use Text Services Manager. */ |
116 | #ifndef USE_MAC_TSM | |
bc0e8412 | 117 | #if TARGET_API_MAC_CARBON |
a625bb4e YM |
118 | #define USE_MAC_TSM 1 |
119 | #endif | |
120 | #endif | |
121 | ||
841fb47f YM |
122 | /* Whether to use HIToolbar. */ |
123 | #ifndef USE_MAC_TOOLBAR | |
aab33444 | 124 | #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 && MAC_OS_X_VERSION_MIN_REQUIRED != 1020 |
841fb47f YM |
125 | #define USE_MAC_TOOLBAR 1 |
126 | #endif | |
127 | #endif | |
128 | ||
15364c8f YM |
129 | #ifndef CGFLOAT_DEFINED |
130 | typedef float CGFloat; | |
131 | #endif | |
132 | ||
1c2c66d5 | 133 | typedef WindowRef Window; |
f3821d29 YM |
134 | #if TARGET_API_MAC_CARBON |
135 | typedef ScrapRef Selection; | |
136 | #else | |
137 | typedef int Selection; | |
138 | #endif | |
139 | #define mac_set_window_title SetWindowTitleWithCFString | |
140 | #define mac_set_window_modified SetWindowModified | |
141 | #define mac_is_window_visible IsWindowVisible | |
142 | #define mac_is_window_collapsed IsWindowCollapsed | |
143 | #define mac_bring_window_to_front BringToFront | |
144 | #define mac_send_window_behind SendBehind | |
145 | #define mac_hide_window HideWindow | |
146 | #define mac_show_window ShowWindow | |
147 | #define mac_collapse_window CollapseWindow | |
148 | #define mac_front_non_floating_window FrontNonFloatingWindow | |
149 | #define mac_active_non_floating_window ActiveNonFloatingWindow | |
150 | #define mac_activate_window ActivateWindow | |
151 | #define mac_move_window_structure MoveWindowStructure | |
152 | #define mac_move_window MoveWindow | |
153 | #define mac_size_window SizeWindow | |
154 | #define mac_get_global_mouse GetGlobalMouse | |
155 | #define mac_is_window_toolbar_visible IsWindowToolbarVisible | |
15364c8f | 156 | #define mac_rect_make(f, x, y, w, h) CGRectMake (x, y, w, h) |
f5d13fd8 YM |
157 | |
158 | #if USE_MAC_IMAGE_IO | |
159 | typedef struct _XImage | |
160 | { | |
161 | int width, height; /* size of image */ | |
162 | char *data; /* pointer to image data */ | |
163 | int bytes_per_line; /* accelarator to next line */ | |
164 | int bits_per_pixel; /* bits per pixel (ZPixmap) */ | |
165 | } *Pixmap; | |
166 | #else | |
e3564461 | 167 | typedef GWorldPtr Pixmap; |
f5d13fd8 | 168 | #endif |
e3564461 | 169 | |
50bf7673 ST |
170 | #define Cursor ThemeCursor |
171 | #define No_Cursor (-1) | |
50bf7673 | 172 | |
1a578e9b AC |
173 | #define FACE_DEFAULT (~0) |
174 | ||
886a6e31 YM |
175 | #if !TARGET_API_MAC_CARBON |
176 | #define GetPixDepth(pmh) ((*(pmh))->pixelSize) | |
177 | #endif | |
178 | ||
1a578e9b AC |
179 | |
180 | /* Emulate XCharStruct. */ | |
b0635670 YM |
181 | /* If the sum of ascent and descent is negative, that means some |
182 | special status specified by enum pcm_status. */ | |
1a578e9b AC |
183 | typedef struct _XCharStruct |
184 | { | |
eaf92438 YM |
185 | short lbearing; /* origin to left edge of raster */ |
186 | short rbearing; /* origin to right edge of raster */ | |
187 | short width; /* advance to next char's origin */ | |
188 | short ascent; /* baseline to top edge of raster */ | |
189 | short descent; /* baseline to bottom edge of raster */ | |
190 | #if 0 | |
191 | unsigned short attributes; /* per char flags (not predefined) */ | |
192 | #endif | |
1a578e9b AC |
193 | } XCharStruct; |
194 | ||
b0635670 YM |
195 | enum pcm_status |
196 | { | |
197 | PCM_VALID = 0, /* pcm data is valid */ | |
198 | PCM_INVALID = -1, /* pcm data is invalid */ | |
199 | }; | |
200 | ||
8c2da0fa ST |
201 | #define STORE_XCHARSTRUCT(xcs, w, bds) \ |
202 | ((xcs).width = (w), \ | |
203 | (xcs).lbearing = (bds).left, \ | |
204 | (xcs).rbearing = (bds).right, \ | |
205 | (xcs).ascent = -(bds).top, \ | |
06505fd8 YM |
206 | (xcs).descent = (bds).bottom) |
207 | ||
1a578e9b | 208 | struct MacFontStruct { |
a6d1cf01 | 209 | char *full_name; |
1a578e9b | 210 | |
e0f712ba | 211 | short mac_fontnum; /* font number of font used in this window */ |
1a578e9b | 212 | int mac_fontsize; /* size of font */ |
e0f712ba | 213 | short mac_fontface; /* plain, bold, italics, etc. */ |
a6d1cf01 YM |
214 | #if TARGET_API_MAC_CARBON |
215 | int mac_scriptcode; /* Mac OS script code for font used */ | |
216 | #else | |
1a578e9b | 217 | short mac_scriptcode; /* Mac OS script code for font used */ |
a6d1cf01 | 218 | #endif |
04904a23 YM |
219 | #if USE_ATSUI |
220 | ATSUStyle mac_style; /* NULL if QuickDraw Text is used */ | |
26d2699b YM |
221 | #if USE_CG_TEXT_DRAWING |
222 | CGFontRef cg_font; /* NULL if ATSUI text drawing is used */ | |
223 | CGGlyph *cg_glyphs; /* Likewise */ | |
224 | #endif | |
04904a23 | 225 | #endif |
1a578e9b AC |
226 | |
227 | /* from Xlib.h */ | |
228 | #if 0 | |
229 | XExtData *ext_data; /* hook for extension to hang data */ | |
230 | Font fid; /* Font id for this font */ | |
231 | unsigned direction; /* hint about the direction font is painted */ | |
e0f712ba | 232 | #endif /* 0 */ |
1a578e9b AC |
233 | unsigned min_char_or_byte2;/* first character */ |
234 | unsigned max_char_or_byte2;/* last character */ | |
235 | unsigned min_byte1; /* first row that exists */ | |
236 | unsigned max_byte1; /* last row that exists */ | |
237 | #if 0 | |
238 | Bool all_chars_exist; /* flag if all characters have nonzero size */ | |
239 | unsigned default_char; /* char to print for undefined character */ | |
240 | int n_properties; /* how many properties there are */ | |
241 | XFontProp *properties; /* pointer to array of additional properties */ | |
e0f712ba | 242 | #endif /* 0 */ |
1a578e9b AC |
243 | XCharStruct min_bounds; /* minimum bounds over all existing char */ |
244 | XCharStruct max_bounds; /* maximum bounds over all existing char */ | |
06505fd8 YM |
245 | union { |
246 | XCharStruct *per_char; /* first_char to last_char information */ | |
b0635670 | 247 | XCharStruct **rows; /* first row to last row information */ |
06505fd8 | 248 | } bounds; |
1a578e9b AC |
249 | int ascent; /* logical extent above baseline for spacing */ |
250 | int descent; /* logical decent below baseline for spacing */ | |
251 | }; | |
252 | ||
253 | typedef struct MacFontStruct MacFontStruct; | |
254 | typedef struct MacFontStruct XFontStruct; | |
255 | ||
ec480ce0 KS |
256 | /* Structure borrowed from Xlib.h to represent two-byte characters. */ |
257 | ||
258 | typedef struct { | |
259 | unsigned char byte1; | |
260 | unsigned char byte2; | |
261 | } XChar2b; | |
262 | ||
263 | #define STORE_XCHAR2B(chp, b1, b2) \ | |
264 | ((chp)->byte1 = (b1), (chp)->byte2 = (b2)) | |
265 | ||
266 | #define XCHAR2B_BYTE1(chp) \ | |
267 | ((chp)->byte1) | |
268 | ||
269 | #define XCHAR2B_BYTE2(chp) \ | |
270 | ((chp)->byte2) | |
271 | ||
1a578e9b AC |
272 | |
273 | /* Emulate X GC's by keeping color and font info in a structure. */ | |
274 | typedef struct _XGCValues | |
275 | { | |
276 | unsigned long foreground; | |
277 | unsigned long background; | |
278 | XFontStruct *font; | |
279 | } XGCValues; | |
280 | ||
623cc1d8 YM |
281 | typedef struct _XGC |
282 | { | |
283 | /* Original value. */ | |
284 | XGCValues xgcv; | |
285 | ||
286 | /* Cached data members follow. */ | |
1a578e9b | 287 | |
623cc1d8 YM |
288 | /* QuickDraw foreground color. */ |
289 | RGBColor fore_color; | |
1a578e9b | 290 | |
623cc1d8 YM |
291 | /* QuickDraw background color. */ |
292 | RGBColor back_color; | |
2be96ef8 | 293 | |
3bfd2d46 YM |
294 | #if USE_CG_DRAWING && MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 |
295 | /* Quartz 2D foreground color. */ | |
296 | CGColorRef cg_fore_color; | |
297 | ||
298 | /* Quartz 2D background color. */ | |
299 | CGColorRef cg_back_color; | |
300 | #endif | |
301 | ||
2be96ef8 | 302 | #define MAX_CLIP_RECTS 2 |
c6c45177 YM |
303 | /* Number of clipping rectangles. */ |
304 | int n_clip_rects; | |
305 | ||
306 | /* QuickDraw clipping region. Ignored if n_clip_rects == 0. */ | |
2be96ef8 YM |
307 | RgnHandle clip_region; |
308 | ||
b0635670 | 309 | #if defined (MAC_OSX) && (USE_ATSUI || USE_CG_DRAWING) |
2be96ef8 YM |
310 | /* Clipping rectangles used in Quartz 2D drawing. The y-coordinate |
311 | is in QuickDraw's. */ | |
312 | CGRect clip_rects[MAX_CLIP_RECTS]; | |
313 | #endif | |
623cc1d8 YM |
314 | } *GC; |
315 | ||
316 | #define GCForeground (1L<<2) | |
317 | #define GCBackground (1L<<3) | |
318 | #define GCFont (1L<<14) | |
319 | #define GCGraphicsExposures 0 | |
1a578e9b AC |
320 | |
321 | /* Bit Gravity */ | |
322 | ||
323 | #define ForgetGravity 0 | |
324 | #define NorthWestGravity 1 | |
325 | #define NorthGravity 2 | |
326 | #define NorthEastGravity 3 | |
327 | #define WestGravity 4 | |
328 | #define CenterGravity 5 | |
329 | #define EastGravity 6 | |
330 | #define SouthWestGravity 7 | |
331 | #define SouthGravity 8 | |
332 | #define SouthEastGravity 9 | |
333 | #define StaticGravity 10 | |
334 | ||
335 | #define NoValue 0x0000 | |
336 | #define XValue 0x0001 | |
337 | #define YValue 0x0002 | |
338 | #define WidthValue 0x0004 | |
339 | #define HeightValue 0x0008 | |
340 | #define AllValues 0x000F | |
341 | #define XNegative 0x0010 | |
342 | #define YNegative 0x0020 | |
343 | ||
b15325b2 ST |
344 | typedef struct { |
345 | long flags; /* marks which fields in this structure are defined */ | |
346 | #if 0 | |
347 | int x, y; /* obsolete for new window mgrs, but clients */ | |
348 | int width, height; /* should set so old wm's don't mess up */ | |
349 | #endif | |
350 | int min_width, min_height; | |
351 | #if 0 | |
352 | int max_width, max_height; | |
353 | #endif | |
354 | int width_inc, height_inc; | |
355 | #if 0 | |
356 | struct { | |
357 | int x; /* numerator */ | |
358 | int y; /* denominator */ | |
359 | } min_aspect, max_aspect; | |
360 | #endif | |
361 | int base_width, base_height; /* added by ICCCM version 1 */ | |
362 | #if 0 | |
363 | int win_gravity; /* added by ICCCM version 1 */ | |
364 | #endif | |
365 | } XSizeHints; | |
366 | ||
1a578e9b AC |
367 | #define USPosition (1L << 0) /* user specified x, y */ |
368 | #define USSize (1L << 1) /* user specified width, height */ | |
369 | ||
370 | #define PPosition (1L << 2) /* program specified position */ | |
371 | #define PSize (1L << 3) /* program specified size */ | |
372 | #define PMinSize (1L << 4) /* program specified minimum size */ | |
373 | #define PMaxSize (1L << 5) /* program specified maximum size */ | |
374 | #define PResizeInc (1L << 6) /* program specified resize increments */ | |
375 | #define PAspect (1L << 7) /* program specified min and max aspect ratios */ | |
376 | #define PBaseSize (1L << 8) /* program specified base for incrementing */ | |
377 | #define PWinGravity (1L << 9) /* program specified window gravity */ | |
378 | ||
e119ad0d KS |
379 | typedef struct { |
380 | int x, y; | |
381 | unsigned width, height; | |
382 | } XRectangle; | |
383 | ||
384 | #define NativeRectangle Rect | |
385 | ||
386 | #define CONVERT_TO_XRECT(xr,nr) \ | |
387 | ((xr).x = (nr).left, \ | |
388 | (xr).y = (nr).top, \ | |
389 | (xr).width = ((nr).right - (nr).left), \ | |
390 | (xr).height = ((nr).bottom - (nr).top)) | |
391 | ||
392 | #define CONVERT_FROM_XRECT(xr,nr) \ | |
393 | ((nr).left = (xr).x, \ | |
394 | (nr).top = (xr).y, \ | |
395 | (nr).right = ((xr).x + (xr).width), \ | |
396 | (nr).bottom = ((xr).y + (xr).height)) | |
397 | ||
398 | #define STORE_NATIVE_RECT(nr,x,y,width,height) \ | |
399 | ((nr).left = (x), \ | |
400 | (nr).top = (y), \ | |
401 | (nr).right = ((nr).left + (width)), \ | |
402 | (nr).bottom = ((nr).top + (height))) | |
403 | ||
f3821d29 YM |
404 | /* Definitions copied from lwlib.h */ |
405 | ||
406 | typedef void * XtPointer; | |
407 | ||
408 | enum button_type | |
409 | { | |
410 | BUTTON_TYPE_NONE, | |
411 | BUTTON_TYPE_TOGGLE, | |
412 | BUTTON_TYPE_RADIO | |
413 | }; | |
414 | ||
415 | /* This structure is based on the one in ../lwlib/lwlib.h, modified | |
416 | for Mac OS. */ | |
417 | typedef struct _widget_value | |
418 | { | |
419 | /* name of widget */ | |
420 | Lisp_Object lname; | |
421 | char* name; | |
422 | /* value (meaning depend on widget type) */ | |
423 | char* value; | |
424 | /* keyboard equivalent. no implications for XtTranslations */ | |
425 | Lisp_Object lkey; | |
426 | char* key; | |
427 | /* Help string or nil if none. | |
428 | GC finds this string through the frame's menu_bar_vector | |
429 | or through menu_items. */ | |
430 | Lisp_Object help; | |
431 | /* true if enabled */ | |
432 | Boolean enabled; | |
433 | /* true if selected */ | |
434 | Boolean selected; | |
435 | /* The type of a button. */ | |
436 | enum button_type button_type; | |
437 | /* true if menu title */ | |
438 | Boolean title; | |
439 | #if 0 | |
440 | /* true if was edited (maintained by get_value) */ | |
441 | Boolean edited; | |
442 | /* true if has changed (maintained by lw library) */ | |
443 | change_type change; | |
444 | /* true if this widget itself has changed, | |
445 | but not counting the other widgets found in the `next' field. */ | |
446 | change_type this_one_change; | |
447 | #endif | |
448 | /* Contents of the sub-widgets, also selected slot for checkbox */ | |
449 | struct _widget_value* contents; | |
450 | /* data passed to callback */ | |
451 | XtPointer call_data; | |
452 | /* next one in the list */ | |
453 | struct _widget_value* next; | |
454 | #if 0 | |
455 | /* slot for the toolkit dependent part. Always initialize to NULL. */ | |
456 | void* toolkit_data; | |
457 | /* tell us if we should free the toolkit data slot when freeing the | |
458 | widget_value itself. */ | |
459 | Boolean free_toolkit_data; | |
460 | ||
461 | /* we resource the widget_value structures; this points to the next | |
462 | one on the free list if this one has been deallocated. | |
463 | */ | |
464 | struct _widget_value *free_list; | |
465 | #endif | |
466 | } widget_value; | |
467 | ||
468 | #if MAC_OS8 | |
469 | #define M_APPLE 234 | |
470 | #define I_ABOUT 1 | |
471 | ||
472 | #define EXTRA_STACK_ALLOC (256 * 1024) | |
473 | ||
474 | #define ARGV_STRING_LIST_ID 129 | |
475 | #define RAM_TOO_LARGE_ALERT_ID 129 | |
476 | #define ABOUT_ALERT_ID 128 | |
477 | #endif | |
478 | ||
479 | #define DIALOG_LEFT_MARGIN (112) | |
480 | #define DIALOG_TOP_MARGIN (24) | |
481 | #define DIALOG_RIGHT_MARGIN (24) | |
482 | #define DIALOG_BOTTOM_MARGIN (20) | |
483 | #define DIALOG_MIN_INNER_WIDTH (338) | |
484 | #define DIALOG_MAX_INNER_WIDTH (564) | |
485 | #define DIALOG_BUTTON_BUTTON_HORIZONTAL_SPACE (12) | |
486 | #define DIALOG_BUTTON_BUTTON_VERTICAL_SPACE (12) | |
487 | #define DIALOG_BUTTON_MIN_WIDTH (68) | |
488 | #define DIALOG_TEXT_MIN_HEIGHT (50) | |
489 | #define DIALOG_TEXT_BUTTONS_VERTICAL_SPACE (10) | |
490 | #define DIALOG_ICON_WIDTH (64) | |
491 | #define DIALOG_ICON_HEIGHT (64) | |
492 | #define DIALOG_ICON_LEFT_MARGIN (24) | |
493 | #define DIALOG_ICON_TOP_MARGIN (15) | |
494 | ||
1a578e9b AC |
495 | #endif /* EMACS_MACGUI_H */ |
496 | ||
ab5796a9 MB |
497 | /* arch-tag: 5a0da49a-35e2-418b-a58c-8a55778ae849 |
498 | (do not change this comment) */ |