diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 45 | ||||
| -rw-r--r-- | src/fileio.c | 2 | ||||
| -rw-r--r-- | src/gtkutil.c | 2 | ||||
| -rw-r--r-- | src/gtkutil.h | 2 | ||||
| -rw-r--r-- | src/macfns.c | 216 | ||||
| -rw-r--r-- | src/macmenu.c | 95 | ||||
| -rw-r--r-- | src/xmenu.c | 56 |
7 files changed, 311 insertions, 107 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d49514b2fc0..14eece1b04e 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,48 @@ | |||
| 1 | 2004-08-30 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * macmenu.c (_widget_value): Added lname and lkey. | ||
| 4 | (single_submenu): Set lname and lkey in widget_value | ||
| 5 | instead of name and key. | ||
| 6 | (update_submenu_strings): New function. | ||
| 7 | (set_frame_menubar): Remove call to inhibit_garbage_collection, | ||
| 8 | call update_submenu_strings. | ||
| 9 | |||
| 10 | * xmenu.c (digest_single_submenu): Set lname and lkey in widget_value | ||
| 11 | instead of name and key. | ||
| 12 | (update_submenu_strings): New function. | ||
| 13 | (set_frame_menubar): Remove call to inhibit_garbage_collection, | ||
| 14 | call update_submenu_strings. | ||
| 15 | |||
| 16 | * gtkutil.h (_widget_value): Added lname and lkey. | ||
| 17 | |||
| 18 | 2004-08-30 Steven Tamm <steventamm@mac.com> | ||
| 19 | |||
| 20 | * macmenu.c (mac_menu_show): Remove shadowing of menu variable | ||
| 21 | by using different names for inner loop variables. | ||
| 22 | |||
| 23 | 2004-08-27 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | ||
| 24 | |||
| 25 | * xmenu.c (set_frame_menubar): Reintroduce inhibit_garbage_collection | ||
| 26 | from 2002-07-15T00:01:34Z!raeburn@raeburn.org so that strings from ENCODE_UTF_8 isn't GC:ed before used. | ||
| 27 | |||
| 28 | * gtkutil.c (xg_create_frame_widgets): Compensate for tool bar when | ||
| 29 | tool bar items is 0. | ||
| 30 | |||
| 31 | 2004-08-26 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | ||
| 32 | |||
| 33 | * macmenu.c (ENCODE_MENU_STRING): Added to handle multibyte | ||
| 34 | strings in menu items. | ||
| 35 | (single_submenu): Use ENCODE_MENU_STRING | ||
| 36 | (mac_menu_show): Use ENCODE_MENU_STRING. Reset grabbed because | ||
| 37 | button release isn't passed to event loop | ||
| 38 | (add_menu_item): Use SetMenuItemWithCFString | ||
| 39 | |||
| 40 | 2004-08-26 Steven Tamm <steventamm@mac.com> | ||
| 41 | |||
| 42 | * fileio.c (Fread_file_name): Call x_file_dialog on carbon on | ||
| 43 | tool-bar/menu click | ||
| 44 | * macfns.c (Fx_file_dialog): Implemented using NavServices | ||
| 45 | |||
| 1 | 2004-08-24 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | 46 | 2004-08-24 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> |
| 2 | 47 | ||
| 3 | * xterm.c (x_catch_errors_unwind): Do not XSync if display has closed. | 48 | * xterm.c (x_catch_errors_unwind): Do not XSync if display has closed. |
diff --git a/src/fileio.c b/src/fileio.c index da544f72234..707b6e96d86 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -6306,7 +6306,7 @@ and `read-file-name-function'. */) | |||
| 6306 | 6306 | ||
| 6307 | GCPRO2 (insdef, default_filename); | 6307 | GCPRO2 (insdef, default_filename); |
| 6308 | 6308 | ||
| 6309 | #if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) | 6309 | #if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (TARGET_API_MAC_CARBON) |
| 6310 | if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) | 6310 | if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) |
| 6311 | && use_dialog_box | 6311 | && use_dialog_box |
| 6312 | && use_file_dialog | 6312 | && use_file_dialog |
diff --git a/src/gtkutil.c b/src/gtkutil.c index 3ffba0ba745..fabdae74dc6 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -793,7 +793,7 @@ xg_create_frame_widgets (f) | |||
| 793 | up in the wrong place as tool bar height has not been taken into account. | 793 | up in the wrong place as tool bar height has not been taken into account. |
| 794 | So we cheat a bit by setting a height that is what it will have | 794 | So we cheat a bit by setting a height that is what it will have |
| 795 | later on when tool bar items are added. */ | 795 | later on when tool bar items are added. */ |
| 796 | if (FRAME_EXTERNAL_TOOL_BAR (f) && FRAME_TOOLBAR_HEIGHT (f) == 0) | 796 | if (FRAME_EXTERNAL_TOOL_BAR (f) && f->n_tool_bar_items == 0) |
| 797 | FRAME_TOOLBAR_HEIGHT (f) = 34; | 797 | FRAME_TOOLBAR_HEIGHT (f) = 34; |
| 798 | 798 | ||
| 799 | 799 | ||
diff --git a/src/gtkutil.h b/src/gtkutil.h index b31ec8c2a1f..b35ab94b2cb 100644 --- a/src/gtkutil.h +++ b/src/gtkutil.h | |||
| @@ -96,10 +96,12 @@ typedef struct xg_menu_item_cb_data_ | |||
| 96 | typedef struct _widget_value | 96 | typedef struct _widget_value |
| 97 | { | 97 | { |
| 98 | /* name of widget */ | 98 | /* name of widget */ |
| 99 | Lisp_Object lname; | ||
| 99 | char *name; | 100 | char *name; |
| 100 | /* value (meaning depend on widget type) */ | 101 | /* value (meaning depend on widget type) */ |
| 101 | char *value; | 102 | char *value; |
| 102 | /* keyboard equivalent. no implications for XtTranslations */ | 103 | /* keyboard equivalent. no implications for XtTranslations */ |
| 104 | Lisp_Object lkey; | ||
| 103 | char *key; | 105 | char *key; |
| 104 | /* Help string or nil if none. | 106 | /* Help string or nil if none. |
| 105 | GC finds this string through the frame's menu_bar_vector | 107 | GC finds this string through the frame's menu_bar_vector |
diff --git a/src/macfns.c b/src/macfns.c index ec014e772e3..fbade05ea17 100644 --- a/src/macfns.c +++ b/src/macfns.c | |||
| @@ -4192,19 +4192,27 @@ Value is t if tooltip was open, nil otherwise. */) | |||
| 4192 | 4192 | ||
| 4193 | 4193 | ||
| 4194 | 4194 | ||
| 4195 | #ifdef TARGET_API_MAC_CARBON | ||
| 4195 | /*********************************************************************** | 4196 | /*********************************************************************** |
| 4196 | File selection dialog | 4197 | File selection dialog |
| 4197 | ***********************************************************************/ | 4198 | ***********************************************************************/ |
| 4198 | 4199 | ||
| 4199 | #if 0 /* MAC_TODO: can standard file dialog */ | 4200 | /** |
| 4201 | There is a relatively standard way to do this using applescript to run | ||
| 4202 | a (choose file) method. However, this doesn't do "the right thing" | ||
| 4203 | by working only if the find-file occurred during a menu or toolbar | ||
| 4204 | click. So we must do the file dialog by hand, using the navigation | ||
| 4205 | manager. This also has more flexibility in determining the default | ||
| 4206 | directory and whether or not we are going to choose a file. | ||
| 4207 | **/ | ||
| 4208 | |||
| 4200 | extern Lisp_Object Qfile_name_history; | 4209 | extern Lisp_Object Qfile_name_history; |
| 4201 | 4210 | ||
| 4202 | DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, | 4211 | DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, |
| 4203 | doc: /* Read file name, prompting with PROMPT in directory DIR. | 4212 | doc: /* Read file name, prompting with PROMPT in directory DIR. |
| 4204 | Use a file selection dialog. | 4213 | Use a file selection dialog. |
| 4205 | Select DEFAULT-FILENAME in the dialog's file selection box, if | 4214 | Select DEFAULT-FILENAME in the dialog's file selection box, if |
| 4206 | specified. Don't let the user enter a file name in the file | 4215 | specified. Ensure that file exists if MUSTMATCH is non-nil. */) |
| 4207 | selection dialog's entry field, if MUSTMATCH is non-nil. */) | ||
| 4208 | (prompt, dir, default_filename, mustmatch) | 4216 | (prompt, dir, default_filename, mustmatch) |
| 4209 | Lisp_Object prompt, dir, default_filename, mustmatch; | 4217 | Lisp_Object prompt, dir, default_filename, mustmatch; |
| 4210 | { | 4218 | { |
| @@ -4212,9 +4220,8 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */) | |||
| 4212 | Lisp_Object file = Qnil; | 4220 | Lisp_Object file = Qnil; |
| 4213 | int count = SPECPDL_INDEX (); | 4221 | int count = SPECPDL_INDEX (); |
| 4214 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 4222 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 4215 | char filename[MAX_PATH + 1]; | 4223 | char filename[1001]; |
| 4216 | char init_dir[MAX_PATH + 1]; | 4224 | int default_filter_index = 1; /* 1: All Files, 2: Directories only */ |
| 4217 | int use_dialog_p = 1; | ||
| 4218 | 4225 | ||
| 4219 | GCPRO5 (prompt, dir, default_filename, mustmatch, file); | 4226 | GCPRO5 (prompt, dir, default_filename, mustmatch, file); |
| 4220 | CHECK_STRING (prompt); | 4227 | CHECK_STRING (prompt); |
| @@ -4223,87 +4230,150 @@ selection dialog's entry field, if MUSTMATCH is non-nil. */) | |||
| 4223 | /* Create the dialog with PROMPT as title, using DIR as initial | 4230 | /* Create the dialog with PROMPT as title, using DIR as initial |
| 4224 | directory and using "*" as pattern. */ | 4231 | directory and using "*" as pattern. */ |
| 4225 | dir = Fexpand_file_name (dir, Qnil); | 4232 | dir = Fexpand_file_name (dir, Qnil); |
| 4226 | strncpy (init_dir, SDATA (dir), MAX_PATH); | ||
| 4227 | init_dir[MAX_PATH] = '\0'; | ||
| 4228 | unixtodos_filename (init_dir); | ||
| 4229 | |||
| 4230 | if (STRINGP (default_filename)) | ||
| 4231 | { | ||
| 4232 | char *file_name_only; | ||
| 4233 | char *full_path_name = SDATA (default_filename); | ||
| 4234 | |||
| 4235 | unixtodos_filename (full_path_name); | ||
| 4236 | |||
| 4237 | file_name_only = strrchr (full_path_name, '\\'); | ||
| 4238 | if (!file_name_only) | ||
| 4239 | file_name_only = full_path_name; | ||
| 4240 | else | ||
| 4241 | { | ||
| 4242 | file_name_only++; | ||
| 4243 | |||
| 4244 | /* If default_file_name is a directory, don't use the open | ||
| 4245 | file dialog, as it does not support selecting | ||
| 4246 | directories. */ | ||
| 4247 | if (!(*file_name_only)) | ||
| 4248 | use_dialog_p = 0; | ||
| 4249 | } | ||
| 4250 | |||
| 4251 | strncpy (filename, file_name_only, MAX_PATH); | ||
| 4252 | filename[MAX_PATH] = '\0'; | ||
| 4253 | } | ||
| 4254 | else | ||
| 4255 | filename[0] = '\0'; | ||
| 4256 | 4233 | ||
| 4257 | if (use_dialog_p) | 4234 | { |
| 4258 | { | 4235 | OSStatus status; |
| 4259 | OPENFILENAME file_details; | 4236 | NavDialogCreationOptions options; |
| 4260 | char *filename_file; | 4237 | NavDialogRef dialogRef; |
| 4238 | NavTypeListHandle fileTypes = NULL; | ||
| 4239 | NavUserAction userAction; | ||
| 4240 | CFStringRef message=NULL, client=NULL, saveName = NULL; | ||
| 4241 | |||
| 4242 | /* No need for a callback function because we are modal */ | ||
| 4243 | NavGetDefaultDialogCreationOptions(&options); | ||
| 4244 | options.modality = kWindowModalityAppModal; | ||
| 4245 | options.location.h = options.location.v = -1; | ||
| 4246 | options.optionFlags = kNavDefaultNavDlogOptions; | ||
| 4247 | options.optionFlags |= kNavAllFilesInPopup; /* All files allowed */ | ||
| 4248 | options.optionFlags |= kNavSelectAllReadableItem; | ||
| 4249 | if (!NILP(prompt)) | ||
| 4250 | { | ||
| 4251 | message = CFStringCreateWithCStringNoCopy(NULL, SDATA(prompt), | ||
| 4252 | kCFStringEncodingUTF8, | ||
| 4253 | kCFAllocatorNull); | ||
| 4254 | options.message = message; | ||
| 4255 | } | ||
| 4256 | /* Don't set the application, let it use default. | ||
| 4257 | client = CFStringCreateWithCStringNoCopy(NULL, "Emacs", | ||
| 4258 | kCFStringEncodingMacRoman, NULL); | ||
| 4259 | options.clientName = client; | ||
| 4260 | */ | ||
| 4261 | |||
| 4262 | /* Do Dired hack copied from w32fns.c */ | ||
| 4263 | if (!NILP(prompt) && strncmp (SDATA(prompt), "Dired", 5) == 0) | ||
| 4264 | status = NavCreateChooseFolderDialog(&options, NULL, NULL, NULL, | ||
| 4265 | &dialogRef); | ||
| 4266 | else if (NILP (mustmatch)) | ||
| 4267 | { | ||
| 4268 | /* This is a save dialog */ | ||
| 4269 | if (!NILP(default_filename)) | ||
| 4270 | { | ||
| 4271 | saveName = CFStringCreateWithCString(NULL, SDATA(default_filename), | ||
| 4272 | kCFStringEncodingUTF8); | ||
| 4273 | options.saveFileName = saveName; | ||
| 4274 | options.optionFlags |= kNavSelectDefaultLocation; | ||
| 4275 | } | ||
| 4276 | /* MAC_TODO: Find a better way to determine if this is a save | ||
| 4277 | or load dialog than comparing dir with default_filename */ | ||
| 4278 | if (EQ(dir, default_filename)) | ||
| 4279 | { | ||
| 4280 | status = NavCreateChooseFileDialog(&options, fileTypes, | ||
| 4281 | NULL, NULL, NULL, NULL, | ||
| 4282 | &dialogRef); | ||
| 4283 | } | ||
| 4284 | else { | ||
| 4285 | status = NavCreatePutFileDialog(&options, | ||
| 4286 | 'TEXT', kNavGenericSignature, | ||
| 4287 | NULL, NULL, &dialogRef); | ||
| 4288 | } | ||
| 4289 | } | ||
| 4290 | else | ||
| 4291 | { | ||
| 4292 | /* This is an open dialog*/ | ||
| 4293 | status = NavCreateChooseFileDialog(&options, fileTypes, | ||
| 4294 | NULL, NULL, NULL, NULL, | ||
| 4295 | &dialogRef); | ||
| 4296 | } | ||
| 4297 | |||
| 4298 | /* Set the default location and continue*/ | ||
| 4299 | if (status == noErr) { | ||
| 4300 | if (!NILP(dir)) { | ||
| 4301 | FSRef defLoc; | ||
| 4302 | AEDesc defLocAed; | ||
| 4303 | status = FSPathMakeRef(SDATA(dir), &defLoc, NULL); | ||
| 4304 | if (status == noErr) | ||
| 4305 | { | ||
| 4306 | AECreateDesc(typeFSRef, &defLoc, sizeof(FSRef), &defLocAed); | ||
| 4307 | NavCustomControl(dialogRef, kNavCtlSetLocation, (void*) &defLocAed); | ||
| 4308 | } | ||
| 4309 | AEDisposeDesc(&defLocAed); | ||
| 4310 | } | ||
| 4261 | 4311 | ||
| 4262 | /* Prevent redisplay. */ | ||
| 4263 | specbind (Qinhibit_redisplay, Qt); | ||
| 4264 | BLOCK_INPUT; | 4312 | BLOCK_INPUT; |
| 4313 | status = NavDialogRun(dialogRef); | ||
| 4314 | UNBLOCK_INPUT; | ||
| 4315 | } | ||
| 4265 | 4316 | ||
| 4266 | bzero (&file_details, sizeof (file_details)); | 4317 | if (saveName) CFRelease(saveName); |
| 4267 | file_details.lStructSize = sizeof (file_details); | 4318 | if (client) CFRelease(client); |
| 4268 | file_details.hwndOwner = FRAME_W32_WINDOW (f); | 4319 | if (message) CFRelease(message); |
| 4269 | file_details.lpstrFile = filename; | ||
| 4270 | file_details.nMaxFile = sizeof (filename); | ||
| 4271 | file_details.lpstrInitialDir = init_dir; | ||
| 4272 | file_details.lpstrTitle = SDATA (prompt); | ||
| 4273 | file_details.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR; | ||
| 4274 | |||
| 4275 | if (!NILP (mustmatch)) | ||
| 4276 | file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; | ||
| 4277 | 4320 | ||
| 4278 | if (GetOpenFileName (&file_details)) | 4321 | if (status == noErr) { |
| 4279 | { | 4322 | userAction = NavDialogGetUserAction(dialogRef); |
| 4280 | dostounix_filename (filename); | 4323 | switch (userAction) |
| 4281 | file = build_string (filename); | 4324 | { |
| 4282 | } | 4325 | case kNavUserActionNone: |
| 4283 | else | 4326 | case kNavUserActionCancel: |
| 4284 | file = Qnil; | 4327 | NavDialogDispose(dialogRef); |
| 4285 | 4328 | Fsignal (Qquit, Qnil); /* Treat cancel like C-g */ | |
| 4286 | UNBLOCK_INPUT; | 4329 | return; |
| 4287 | file = unbind_to (count, file); | 4330 | case kNavUserActionOpen: |
| 4331 | case kNavUserActionChoose: | ||
| 4332 | case kNavUserActionSaveAs: | ||
| 4333 | { | ||
| 4334 | NavReplyRecord reply; | ||
| 4335 | AEDesc aed; | ||
| 4336 | FSRef fsRef; | ||
| 4337 | status = NavDialogGetReply(dialogRef, &reply); | ||
| 4338 | AECoerceDesc(&reply.selection, typeFSRef, &aed); | ||
| 4339 | AEGetDescData(&aed, (void *) &fsRef, sizeof (FSRef)); | ||
| 4340 | FSRefMakePath(&fsRef, (UInt8 *) filename, 1000); | ||
| 4341 | AEDisposeDesc(&aed); | ||
| 4342 | if (reply.saveFileName) | ||
| 4343 | { | ||
| 4344 | /* If it was a saved file, we need to add the file name */ | ||
| 4345 | int len = strlen(filename); | ||
| 4346 | if (len && filename[len-1] != '/') | ||
| 4347 | filename[len++] = '/'; | ||
| 4348 | CFStringGetCString(reply.saveFileName, filename+len, | ||
| 4349 | 1000-len, kCFStringEncodingUTF8); | ||
| 4350 | } | ||
| 4351 | file = DECODE_FILE(build_string (filename)); | ||
| 4352 | NavDisposeReply(&reply); | ||
| 4353 | } | ||
| 4354 | break; | ||
| 4355 | } | ||
| 4356 | NavDialogDispose(dialogRef); | ||
| 4288 | } | 4357 | } |
| 4289 | /* Open File dialog will not allow folders to be selected, so resort | 4358 | else { |
| 4290 | to minibuffer completing reads for directories. */ | 4359 | /* Fall back on minibuffer if there was a problem */ |
| 4291 | else | 4360 | file = Fcompleting_read (prompt, intern ("read-file-name-internal"), |
| 4292 | file = Fcompleting_read (prompt, intern ("read-file-name-internal"), | 4361 | dir, mustmatch, dir, Qfile_name_history, |
| 4293 | dir, mustmatch, dir, Qfile_name_history, | 4362 | default_filename, Qnil); |
| 4294 | default_filename, Qnil); | 4363 | } |
| 4364 | } | ||
| 4295 | 4365 | ||
| 4296 | UNGCPRO; | 4366 | UNGCPRO; |
| 4297 | 4367 | ||
| 4298 | /* Make "Cancel" equivalent to C-g. */ | 4368 | /* Make "Cancel" equivalent to C-g. */ |
| 4299 | if (NILP (file)) | 4369 | if (NILP (file)) |
| 4300 | Fsignal (Qquit, Qnil); | 4370 | Fsignal (Qquit, Qnil); |
| 4301 | 4371 | ||
| 4302 | return unbind_to (count, file); | 4372 | return unbind_to (count, file); |
| 4303 | } | 4373 | } |
| 4304 | #endif /* MAC_TODO */ | ||
| 4305 | 4374 | ||
| 4306 | 4375 | ||
| 4376 | #endif | ||
| 4307 | 4377 | ||
| 4308 | /*********************************************************************** | 4378 | /*********************************************************************** |
| 4309 | Initialization | 4379 | Initialization |
| @@ -4507,7 +4577,7 @@ Chinese, Japanese, and Korean. */); | |||
| 4507 | last_show_tip_args = Qnil; | 4577 | last_show_tip_args = Qnil; |
| 4508 | staticpro (&last_show_tip_args); | 4578 | staticpro (&last_show_tip_args); |
| 4509 | 4579 | ||
| 4510 | #if 0 /* MAC_TODO */ | 4580 | #if TARGET_API_MAC_CARBON |
| 4511 | defsubr (&Sx_file_dialog); | 4581 | defsubr (&Sx_file_dialog); |
| 4512 | #endif | 4582 | #endif |
| 4513 | } | 4583 | } |
diff --git a/src/macmenu.c b/src/macmenu.c index d205ee3b877..88012b01f73 100644 --- a/src/macmenu.c +++ b/src/macmenu.c | |||
| @@ -90,10 +90,12 @@ enum button_type | |||
| 90 | typedef struct _widget_value | 90 | typedef struct _widget_value |
| 91 | { | 91 | { |
| 92 | /* name of widget */ | 92 | /* name of widget */ |
| 93 | Lisp_Object lname; | ||
| 93 | char* name; | 94 | char* name; |
| 94 | /* value (meaning depend on widget type) */ | 95 | /* value (meaning depend on widget type) */ |
| 95 | char* value; | 96 | char* value; |
| 96 | /* keyboard equivalent. no implications for XtTranslations */ | 97 | /* keyboard equivalent. no implications for XtTranslations */ |
| 98 | Lisp_Object lkey; | ||
| 97 | char* key; | 99 | char* key; |
| 98 | /* Help string or nil if none. | 100 | /* Help string or nil if none. |
| 99 | GC finds this string through the frame's menu_bar_vector | 101 | GC finds this string through the frame's menu_bar_vector |
| @@ -163,6 +165,12 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; | |||
| 163 | 165 | ||
| 164 | extern Lisp_Object Qmenu_bar_update_hook; | 166 | extern Lisp_Object Qmenu_bar_update_hook; |
| 165 | 167 | ||
| 168 | #if TARGET_API_MAC_CARBON | ||
| 169 | #define ENCODE_MENU_STRING(str) ENCODE_UTF_8 (str) | ||
| 170 | #else | ||
| 171 | #define ENCODE_MENU_STRING(str) ENCODE_SYSTEM (str) | ||
| 172 | #endif | ||
| 173 | |||
| 166 | void set_frame_menubar (); | 174 | void set_frame_menubar (); |
| 167 | 175 | ||
| 168 | static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, | 176 | static void push_menu_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, |
| @@ -1215,12 +1223,9 @@ single_submenu (item_key, item_name, maps) | |||
| 1215 | save_wv->next = wv; | 1223 | save_wv->next = wv; |
| 1216 | else | 1224 | else |
| 1217 | first_wv->contents = wv; | 1225 | first_wv->contents = wv; |
| 1218 | wv->name = pane_string; | 1226 | wv->lname = pane_name; |
| 1219 | /* Ignore the @ that means "separate pane". | 1227 | /* Set value to 1 so update_submenu_strings can handle '@' */ |
| 1220 | This is a kludge, but this isn't worth more time. */ | 1228 | wv->value = (char *)1; |
| 1221 | if (!NILP (prefix) && wv->name[0] == '@') | ||
| 1222 | wv->name++; | ||
| 1223 | wv->value = 0; | ||
| 1224 | wv->enabled = 1; | 1229 | wv->enabled = 1; |
| 1225 | wv->button_type = BUTTON_TYPE_NONE; | 1230 | wv->button_type = BUTTON_TYPE_NONE; |
| 1226 | wv->help = Qnil; | 1231 | wv->help = Qnil; |
| @@ -1246,13 +1251,13 @@ single_submenu (item_key, item_name, maps) | |||
| 1246 | #ifndef HAVE_MULTILINGUAL_MENU | 1251 | #ifndef HAVE_MULTILINGUAL_MENU |
| 1247 | if (STRING_MULTIBYTE (item_name)) | 1252 | if (STRING_MULTIBYTE (item_name)) |
| 1248 | { | 1253 | { |
| 1249 | item_name = ENCODE_SYSTEM (item_name); | 1254 | item_name = ENCODE_MENU_STRING (item_name); |
| 1250 | AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; | 1255 | AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
| 1251 | } | 1256 | } |
| 1252 | 1257 | ||
| 1253 | if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) | 1258 | if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
| 1254 | { | 1259 | { |
| 1255 | descrip = ENCODE_SYSTEM (descrip); | 1260 | descrip = ENCODE_MENU_STRING (descrip); |
| 1256 | AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; | 1261 | AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
| 1257 | } | 1262 | } |
| 1258 | #endif /* not HAVE_MULTILINGUAL_MENU */ | 1263 | #endif /* not HAVE_MULTILINGUAL_MENU */ |
| @@ -1263,9 +1268,9 @@ single_submenu (item_key, item_name, maps) | |||
| 1263 | else | 1268 | else |
| 1264 | save_wv->contents = wv; | 1269 | save_wv->contents = wv; |
| 1265 | 1270 | ||
| 1266 | wv->name = (char *) SDATA (item_name); | 1271 | wv->lname = item_name; |
| 1267 | if (!NILP (descrip)) | 1272 | if (!NILP (descrip)) |
| 1268 | wv->key = (char *) SDATA (descrip); | 1273 | wv->lkey = descrip; |
| 1269 | wv->value = 0; | 1274 | wv->value = 0; |
| 1270 | /* The EMACS_INT cast avoids a warning. There's no problem | 1275 | /* The EMACS_INT cast avoids a warning. There's no problem |
| 1271 | as long as pointers have enough bits to hold small integers. */ | 1276 | as long as pointers have enough bits to hold small integers. */ |
| @@ -1304,6 +1309,41 @@ single_submenu (item_key, item_name, maps) | |||
| 1304 | 1309 | ||
| 1305 | return first_wv; | 1310 | return first_wv; |
| 1306 | } | 1311 | } |
| 1312 | /* Walk through the widget_value tree starting at FIRST_WV and update | ||
| 1313 | the char * pointers from the corresponding lisp values. | ||
| 1314 | We do this after building the whole tree, since GC may happen while the | ||
| 1315 | tree is constructed, and small strings are relocated. So we must wait | ||
| 1316 | until no GC can happen before storing pointers into lisp values. */ | ||
| 1317 | static void | ||
| 1318 | update_submenu_strings (first_wv) | ||
| 1319 | widget_value *first_wv; | ||
| 1320 | { | ||
| 1321 | widget_value *wv; | ||
| 1322 | |||
| 1323 | for (wv = first_wv; wv; wv = wv->next) | ||
| 1324 | { | ||
| 1325 | if (wv->lname && ! NILP (wv->lname)) | ||
| 1326 | { | ||
| 1327 | wv->name = SDATA (wv->lname); | ||
| 1328 | |||
| 1329 | /* Ignore the @ that means "separate pane". | ||
| 1330 | This is a kludge, but this isn't worth more time. */ | ||
| 1331 | if (wv->value == (char *)1) | ||
| 1332 | { | ||
| 1333 | if (wv->name[0] == '@') | ||
| 1334 | wv->name++; | ||
| 1335 | wv->value = 0; | ||
| 1336 | } | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | if (wv->lkey && ! NILP (wv->lkey)) | ||
| 1340 | wv->key = SDATA (wv->lkey); | ||
| 1341 | |||
| 1342 | if (wv->contents) | ||
| 1343 | update_submenu_strings (wv->contents); | ||
| 1344 | } | ||
| 1345 | } | ||
| 1346 | |||
| 1307 | 1347 | ||
| 1308 | /* Set the contents of the menubar widgets of frame F. | 1348 | /* Set the contents of the menubar widgets of frame F. |
| 1309 | The argument FIRST_TIME is currently ignored; | 1349 | The argument FIRST_TIME is currently ignored; |
| @@ -1382,8 +1422,6 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1382 | 1422 | ||
| 1383 | items = FRAME_MENU_BAR_ITEMS (f); | 1423 | items = FRAME_MENU_BAR_ITEMS (f); |
| 1384 | 1424 | ||
| 1385 | inhibit_garbage_collection (); | ||
| 1386 | |||
| 1387 | /* Save the frame's previous menu bar contents data. */ | 1425 | /* Save the frame's previous menu bar contents data. */ |
| 1388 | if (previous_menu_items_used) | 1426 | if (previous_menu_items_used) |
| 1389 | bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, | 1427 | bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, |
| @@ -1448,6 +1486,7 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 1448 | if (NILP (string)) | 1486 | if (NILP (string)) |
| 1449 | break; | 1487 | break; |
| 1450 | wv->name = (char *) SDATA (string); | 1488 | wv->name = (char *) SDATA (string); |
| 1489 | update_submenu_strings (wv->contents); | ||
| 1451 | wv = wv->next; | 1490 | wv = wv->next; |
| 1452 | } | 1491 | } |
| 1453 | 1492 | ||
| @@ -1705,12 +1744,12 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1705 | #ifndef HAVE_MULTILINGUAL_MENU | 1744 | #ifndef HAVE_MULTILINGUAL_MENU |
| 1706 | if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) | 1745 | if (STRINGP (item_name) && STRING_MULTIBYTE (item_name)) |
| 1707 | { | 1746 | { |
| 1708 | item_name = ENCODE_SYSTEM (item_name); | 1747 | item_name = ENCODE_MENU_STRING (item_name); |
| 1709 | AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; | 1748 | AREF (menu_items, i + MENU_ITEMS_ITEM_NAME) = item_name; |
| 1710 | } | 1749 | } |
| 1711 | if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) | 1750 | if (STRINGP (descrip) && STRING_MULTIBYTE (descrip)) |
| 1712 | { | 1751 | { |
| 1713 | descrip = ENCODE_SYSTEM (descrip); | 1752 | descrip = ENCODE_MENU_STRING (descrip); |
| 1714 | AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; | 1753 | AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY) = descrip; |
| 1715 | } | 1754 | } |
| 1716 | #endif /* not HAVE_MULTILINGUAL_MENU */ | 1755 | #endif /* not HAVE_MULTILINGUAL_MENU */ |
| @@ -1764,7 +1803,7 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1764 | 1803 | ||
| 1765 | #ifndef HAVE_MULTILINGUAL_MENU | 1804 | #ifndef HAVE_MULTILINGUAL_MENU |
| 1766 | if (STRING_MULTIBYTE (title)) | 1805 | if (STRING_MULTIBYTE (title)) |
| 1767 | title = ENCODE_SYSTEM (title); | 1806 | title = ENCODE_MENU_STRING (title); |
| 1768 | #endif | 1807 | #endif |
| 1769 | wv_title->name = (char *) SDATA (title); | 1808 | wv_title->name = (char *) SDATA (title); |
| 1770 | wv_title->enabled = TRUE; | 1809 | wv_title->enabled = TRUE; |
| @@ -1801,9 +1840,9 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1801 | /* Get the refcon to find the correct item*/ | 1840 | /* Get the refcon to find the correct item*/ |
| 1802 | if (menu_item_selection) | 1841 | if (menu_item_selection) |
| 1803 | { | 1842 | { |
| 1804 | menu = GetMenuHandle (HiWord (menu_item_choice)); | 1843 | MenuHandle sel_menu = GetMenuHandle (HiWord (menu_item_choice)); |
| 1805 | if (menu) { | 1844 | if (sel_menu) { |
| 1806 | GetMenuItemRefCon (menu, menu_item_selection, &refcon); | 1845 | GetMenuItemRefCon (sel_menu, menu_item_selection, &refcon); |
| 1807 | } | 1846 | } |
| 1808 | } | 1847 | } |
| 1809 | 1848 | ||
| @@ -1813,6 +1852,10 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1813 | discard_mouse_events (); | 1852 | discard_mouse_events (); |
| 1814 | #endif | 1853 | #endif |
| 1815 | 1854 | ||
| 1855 | /* Must reset this manually because the button release event is not | ||
| 1856 | passed to Emacs event loop. */ | ||
| 1857 | FRAME_MAC_DISPLAY_INFO (f)->grabbed = 0; | ||
| 1858 | |||
| 1816 | /* Free the widget_value objects we used to specify the | 1859 | /* Free the widget_value objects we used to specify the |
| 1817 | contents. */ | 1860 | contents. */ |
| 1818 | free_menubar_widget_value_tree (first_wv); | 1861 | free_menubar_widget_value_tree (first_wv); |
| @@ -1821,11 +1864,11 @@ mac_menu_show (f, x, y, for_click, keymaps, title, error) | |||
| 1821 | { | 1864 | { |
| 1822 | int i = MIN_POPUP_SUBMENU_ID; | 1865 | int i = MIN_POPUP_SUBMENU_ID; |
| 1823 | MenuHandle submenu = GetMenuHandle (i); | 1866 | MenuHandle submenu = GetMenuHandle (i); |
| 1824 | while (menu != NULL) | 1867 | while (submenu != NULL) |
| 1825 | { | 1868 | { |
| 1826 | DeleteMenu (i); | 1869 | DeleteMenu (i); |
| 1827 | DisposeMenu (menu); | 1870 | DisposeMenu (submenu); |
| 1828 | menu = GetMenuHandle (++i); | 1871 | submenu = GetMenuHandle (++i); |
| 1829 | } | 1872 | } |
| 1830 | } | 1873 | } |
| 1831 | 1874 | ||
| @@ -2219,8 +2262,18 @@ add_menu_item (MenuHandle menu, widget_value *wv, int submenu, | |||
| 2219 | strncat (item_name, wv->key, 255); | 2262 | strncat (item_name, wv->key, 255); |
| 2220 | } | 2263 | } |
| 2221 | item_name[255] = 0; | 2264 | item_name[255] = 0; |
| 2265 | #if TARGET_API_MAC_CARBON | ||
| 2266 | { | ||
| 2267 | CFStringRef string = | ||
| 2268 | CFStringCreateWithCString (NULL, item_name, kCFStringEncodingUTF8); | ||
| 2269 | |||
| 2270 | SetMenuItemTextWithCFString (menu, pos, string); | ||
| 2271 | CFRelease (string); | ||
| 2272 | } | ||
| 2273 | #else | ||
| 2222 | c2pstr (item_name); | 2274 | c2pstr (item_name); |
| 2223 | SetMenuItemText (menu, pos, item_name); | 2275 | SetMenuItemText (menu, pos, item_name); |
| 2276 | #endif | ||
| 2224 | 2277 | ||
| 2225 | if (wv->enabled && !force_disable) | 2278 | if (wv->enabled && !force_disable) |
| 2226 | #if TARGET_API_MAC_CARBON | 2279 | #if TARGET_API_MAC_CARBON |
diff --git a/src/xmenu.c b/src/xmenu.c index 2ca6e247e12..aa963935262 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -1701,12 +1701,9 @@ digest_single_submenu (start, end, top_level_items) | |||
| 1701 | save_wv->next = wv; | 1701 | save_wv->next = wv; |
| 1702 | else | 1702 | else |
| 1703 | first_wv->contents = wv; | 1703 | first_wv->contents = wv; |
| 1704 | wv->name = pane_string; | 1704 | wv->lname = pane_name; |
| 1705 | /* Ignore the @ that means "separate pane". | 1705 | /* Set value to 1 so update_submenu_strings can handle '@' */ |
| 1706 | This is a kludge, but this isn't worth more time. */ | 1706 | wv->value = (char *)1; |
| 1707 | if (!NILP (prefix) && wv->name[0] == '@') | ||
| 1708 | wv->name++; | ||
| 1709 | wv->value = 0; | ||
| 1710 | wv->enabled = 1; | 1707 | wv->enabled = 1; |
| 1711 | wv->button_type = BUTTON_TYPE_NONE; | 1708 | wv->button_type = BUTTON_TYPE_NONE; |
| 1712 | wv->help = Qnil; | 1709 | wv->help = Qnil; |
| @@ -1749,9 +1746,9 @@ digest_single_submenu (start, end, top_level_items) | |||
| 1749 | else | 1746 | else |
| 1750 | save_wv->contents = wv; | 1747 | save_wv->contents = wv; |
| 1751 | 1748 | ||
| 1752 | wv->name = (char *) SDATA (item_name); | 1749 | wv->lname = item_name; |
| 1753 | if (!NILP (descrip)) | 1750 | if (!NILP (descrip)) |
| 1754 | wv->key = (char *) SDATA (descrip); | 1751 | wv->lkey = descrip; |
| 1755 | wv->value = 0; | 1752 | wv->value = 0; |
| 1756 | /* The EMACS_INT cast avoids a warning. There's no problem | 1753 | /* The EMACS_INT cast avoids a warning. There's no problem |
| 1757 | as long as pointers have enough bits to hold small integers. */ | 1754 | as long as pointers have enough bits to hold small integers. */ |
| @@ -1790,6 +1787,42 @@ digest_single_submenu (start, end, top_level_items) | |||
| 1790 | 1787 | ||
| 1791 | return first_wv; | 1788 | return first_wv; |
| 1792 | } | 1789 | } |
| 1790 | |||
| 1791 | /* Walk through the widget_value tree starting at FIRST_WV and update | ||
| 1792 | the char * pointers from the corresponding lisp values. | ||
| 1793 | We do this after building the whole tree, since GC may happen while the | ||
| 1794 | tree is constructed, and small strings are relocated. So we must wait | ||
| 1795 | until no GC can happen before storing pointers into lisp values. */ | ||
| 1796 | static void | ||
| 1797 | update_submenu_strings (first_wv) | ||
| 1798 | widget_value *first_wv; | ||
| 1799 | { | ||
| 1800 | widget_value *wv; | ||
| 1801 | |||
| 1802 | for (wv = first_wv; wv; wv = wv->next) | ||
| 1803 | { | ||
| 1804 | if (wv->lname && ! NILP (wv->lname)) | ||
| 1805 | { | ||
| 1806 | wv->name = SDATA (wv->lname); | ||
| 1807 | |||
| 1808 | /* Ignore the @ that means "separate pane". | ||
| 1809 | This is a kludge, but this isn't worth more time. */ | ||
| 1810 | if (wv->value == (char *)1) | ||
| 1811 | { | ||
| 1812 | if (wv->name[0] == '@') | ||
| 1813 | wv->name++; | ||
| 1814 | wv->value = 0; | ||
| 1815 | } | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | if (wv->lkey && ! NILP (wv->lkey)) | ||
| 1819 | wv->key = SDATA (wv->lkey); | ||
| 1820 | |||
| 1821 | if (wv->contents) | ||
| 1822 | update_submenu_strings (wv->contents); | ||
| 1823 | } | ||
| 1824 | } | ||
| 1825 | |||
| 1793 | 1826 | ||
| 1794 | /* Recompute all the widgets of frame F, when the menu bar has been | 1827 | /* Recompute all the widgets of frame F, when the menu bar has been |
| 1795 | changed. Value is non-zero if widgets were updated. */ | 1828 | changed. Value is non-zero if widgets were updated. */ |
| @@ -2022,9 +2055,10 @@ set_frame_menubar (f, first_time, deep_p) | |||
| 2022 | Lisp_Object string; | 2055 | Lisp_Object string; |
| 2023 | string = XVECTOR (items)->contents[i + 1]; | 2056 | string = XVECTOR (items)->contents[i + 1]; |
| 2024 | if (NILP (string)) | 2057 | if (NILP (string)) |
| 2025 | break; | 2058 | break; |
| 2026 | wv->name = (char *) SDATA (string); | 2059 | wv->name = (char *) SDATA (string); |
| 2027 | wv = wv->next; | 2060 | update_submenu_strings (wv->contents); |
| 2061 | wv = wv->next; | ||
| 2028 | } | 2062 | } |
| 2029 | 2063 | ||
| 2030 | f->menu_bar_vector = menu_items; | 2064 | f->menu_bar_vector = menu_items; |