1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #ifdef HAVE_CONFIG_H
34 #include "../config.h"
35 #endif
36
37 #include "nedit.h"
38
39 #include "file.h"
40 #include "preferences.h"
41 #include "editorconfig.h"
42 #include "regularExp.h"
43 #include "selection.h"
44 #include "tags.h"
45 #include "menu.h"
46 #include "macro.h"
47 #include "search.h"
48 #include "server.h"
49 #include "interpret.h"
50 #include "parse.h"
51 #include "help.h"
52 #include "text.h"
53 #include "../util/misc.h"
54 #include "../util/printUtils.h"
55 #include "../util/fileUtils.h"
56 #include "../util/filedialog.h"
57 #include "../util/getfiles.h"
58 #include "../util/motif.h"
59 #include "../util/nedit_malloc.h"
60 #include "../util/xdnd.h"
61 #include "filter.h"
62
63 #include <ctype.h>
64 #include <limits.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68 #include <unistd.h>
69 #include <errno.h>
70 #include <langinfo.h>
71
72 #ifndef NO_XMIM
73 #include <X11/Xlocale.h>
74 #else
75 #include <locale.h>
76 #endif
77
78 #include <X11/Intrinsic.h>
79 #include <Xm/Xm.h>
80 #include <Xm/XmP.h>
81
82 #if XmVersion >=
1002
83 #include <Xm/RepType.h>
84 #endif
85
86
87 #ifndef __MVS__
88 #include <sys/param.h>
89 #endif
90
91 #ifdef HAVE_DEBUG_H
92 #include "../debug.h"
93 #endif
94
95 static void nextArg(
int argc,
char **argv,
int *argIndex);
96 static int checkDoMacroArg(
const char *macro);
97 static String neditLanguageProc(Display *dpy, String xnl, XtPointer closure);
98 static void maskArgvKeywords(
int argc,
char **argv,
const char **maskArgs);
99 static void unmaskArgvKeywords(
int argc,
char **argv,
const char **maskArgs);
100 static void fixupBrokenXKeysymDB(
void);
101 static void patchResourcesForVisual(
void);
102 static void patchResourcesForKDEbug(
void);
103 static unsigned char* sanitizeVirtualKeyBindings(
void);
104 static int sortAlphabetical(
const void* k1,
const void* k2);
105 static int virtKeyBindingsAreInvalid(
const unsigned char* bindings);
106 static void restoreInsaneVirtualKeyBindings(
unsigned char* bindings);
107 static void noWarningFilter(String);
108 static void showWarningFilter(String);
109 static void dndOpenFileCB(Widget w, XtPointer value, XtPointer data);
110
111 static XrmDatabase defaultResourceDB;
112
113 WindowInfo *WindowList =
NULL;
114 Display *TheDisplay =
NULL;
115 char *ArgV0 =
NULL;
116 Boolean IsServer = False;
117 Boolean BackgroundRun = False;
118 Widget TheAppShell;
119
120
121
122
123
124
125
126
127
128
129
130
131
132 #define NEDIT_DEFAULT_FONT "-*-helvetica-medium-r-normal-*-14-*-*-*-*-*-iso8859-1," \
133 "-*-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-1=BOLD," \
134 "-*-helvetica-medium-o-normal-*-14-*-*-*-*-*-iso8859-1=ITALIC"
135
136 #define NEDIT_FIXED_FONT "-*-courier-medium-r-normal-*-14-*-*-*-*-*-iso8859-1," \
137 "-*-courier-bold-r-normal-*-14-*-*-*-*-*-iso8859-1=BOLD," \
138 "-*-courier-medium-o-normal-*-14-*-*-*-*-*-iso8859-1=ITALIC"
139
140 #define NEDIT_DEFAULT_BG "#b3b3b3"
141
142 #define NEDIT_TEXT_TRANSLATIONS "#override\\n" \
143 "Ctrl~Alt~Meta<KeyPress>v: paste-clipboard()\\n" \
144 "Ctrl~Alt~Meta<KeyPress>c: copy-clipboard()\\n" \
145 "Ctrl~Alt~Meta<KeyPress>x: cut-clipboard()\\n" \
146 "Ctrl~Alt~Meta<KeyPress>u: delete-to-start-of-line()\\n"
147
148 #define NEDIT_XFT_DEFAULT_FONT "Sans"
149 #define NEDIT_XFT_FIXED_FONT "Monospace"
150
151 static char *fallbackResources[] = {
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 #if (XmVersion >=
2003 && XmUPDATE_LEVEL >=
3 &&
USE_XFT ==
1)
171 "*buttonRenderTable: defaultRT",
172 "*labelRenderTable: defaultRT",
173 "*textRenderTable: fixedRT",
174 "*defaultRT.fontType: FONT_IS_XFT",
175 "*defaultRT.fontName: " NEDIT_XFT_DEFAULT_FONT,
176 "*defaultRT.fontSize: 9",
177 "*fixedRT.fontType: FONT_IS_XFT",
178 "*fixedRT.fontName: Monospace",
179 "*fixedRT.fontSize: 9",
180 #elif LESSTIF_VERSION
181 "*FontList: " NEDIT_DEFAULT_FONT,
182 "*XmText.FontList: " NEDIT_FIXED_FONT,
183 "*XmTextField.FontList: " NEDIT_FIXED_FONT,
184 "*XmList.FontList: " NEDIT_FIXED_FONT,
185 "*XmFileSelectionBox*XmList.FontList: " NEDIT_FIXED_FONT,
186 #else
187 "*buttonFontList: " NEDIT_DEFAULT_FONT,
188 "*labelFontList: " NEDIT_DEFAULT_FONT,
189 "*textFontList: " NEDIT_FIXED_FONT,
190 #endif
191 #ifdef XNE_TEXTFIELD
192 "*XmTextField.XftFont: Monospace:size=10",
193 #endif
194
195
196
197
198
199 "*XmText.foreground: " NEDIT_DEFAULT_FG,
200 "*XmText.background: " NEDIT_DEFAULT_TEXT_BG,
201 "*XmList.foreground: " NEDIT_DEFAULT_FG,
202 "*XmList.background: " NEDIT_DEFAULT_TEXT_BG,
203 "*XmTextField.foreground: " NEDIT_DEFAULT_FG,
204 "*XmTextField.background: " NEDIT_DEFAULT_TEXT_BG,
205
206 "*XmContainer.background: " NEDIT_DEFAULT_TEXT_BG,
207 "*XmIconGadget.background: " NEDIT_DEFAULT_TEXT_BG,
208
209 "*pbbutton.shadowThickness: 1",
210 "*pbbutton.highlightThickness: 1",
211
212 "*tabButton.shadowThickness: 1",
213
214 "*XmContainer.outlineIndentation: 30",
215 "*XmContainer.outlineColumnWidth: 6cm",
216 "*XmContainer.detailTabList: +3cm,+3cm,+3cm",
217
218
219 "*XmText.baseTranslations: " NEDIT_TEXT_TRANSLATIONS,
220 "*XmTextField.baseTranslations: " NEDIT_TEXT_TRANSLATIONS,
221
222 "*XmLFolder.highlightThickness: 0",
223 "*XmLFolder.shadowThickness: 1",
224 "*XmLFolder.maxTabWidth: 150",
225 "*XmLFolder.traversalOn: False",
226 "*XmLFolder.inactiveForeground: #666" ,
227 "*tab.alignment: XmALIGNMENT_BEGINNING",
228 "*tab.marginWidth: 0",
229 "*tab.marginHeight: 1",
230
231
232 "*XmFileSelectionBox.resizePolicy: XmRESIZE_NONE",
233 "*XmFileSelectionBox.textAccelerators:",
234 "*XmFileSelectionBox.pathMode: XmPATH_MODE_RELATIVE",
235 "*XmFileSelectionBox.width: 500",
236 "*XmFileSelectionBox.height: 400",
237
238
239
240
241
242
243 "*newFolder.labelString: New Folder",
244 "*newFolder.labelType: XmPIXMAP",
245
246 "*text.lineNumForeground: " NEDIT_DEFAULT_LINENO_FG,
247 "*text.background: " NEDIT_DEFAULT_TEXT_BG,
248 "*text.foreground: " NEDIT_DEFAULT_FG,
249 "*text.highlightForeground: " NEDIT_DEFAULT_HI_FG,
250 "*text.highlightBackground: " NEDIT_DEFAULT_HI_BG,
251 "*textFrame.shadowThickness: 1",
252 "*menuBar.marginHeight: 0",
253 "*menuBar.shadowThickness: 1",
254 "*pane.sashHeight: 11",
255 "*pane.sashWidth: 11",
256 "*pane.marginWidth: 0",
257 "*pane.marginHeight: 0",
258 "*scrolledW*spacing: 0",
259 "*text.selectionArrayCount: 3",
260 "*helpText.background: " NEDIT_DEFAULT_HELP_BG,
261 "*helpText.foreground: " NEDIT_DEFAULT_HELP_FG,
262 "*helpText.selectBackground: " NEDIT_DEFAULT_BG,
263 "*statsLine.background: " NEDIT_DEFAULT_BG,
264 "*statsLine.FontList: " NEDIT_DEFAULT_FONT,
265 "*calltip.background: LemonChiffon1",
266 "*calltip.foreground: black",
267 "*iSearchForm*highlightThickness: 1",
268 "*fileMenu.tearOffModel: XmTEAR_OFF_ENABLED",
269 "*editMenu.tearOffModel: XmTEAR_OFF_ENABLED",
270 "*searchMenu.tearOffModel: XmTEAR_OFF_ENABLED",
271 "*preferencesMenu.tearOffModel: XmTEAR_OFF_ENABLED",
272 "*windowsMenu.tearOffModel: XmTEAR_OFF_ENABLED",
273 "*shellMenu.tearOffModel: XmTEAR_OFF_ENABLED",
274 "*macroMenu.tearOffModel: XmTEAR_OFF_ENABLED",
275 "*helpMenu.tearOffModel: XmTEAR_OFF_ENABLED",
276 "*fileMenu.mnemonic: F",
277 "*fileMenu.new.accelerator: Ctrl<Key>n",
278 "*fileMenu.new.acceleratorText: Ctrl+N",
279 "*fileMenu.newOpposite.accelerator: Shift Ctrl<Key>n",
280 "*fileMenu.newOpposite.acceleratorText: Shift+Ctrl+N",
281 "*fileMenu.open.accelerator: Ctrl<Key>o",
282 "*fileMenu.open.acceleratorText: Ctrl+O",
283 "*fileMenu.openSelected.accelerator: Ctrl<Key>y",
284 "*fileMenu.openSelected.acceleratorText: Ctrl+Y",
285 "*fileMenu.close.accelerator: Ctrl<Key>w",
286 "*fileMenu.close.acceleratorText: Ctrl+W",
287 "*fileMenu.save.accelerator: Ctrl<Key>s",
288 "*fileMenu.save.acceleratorText: Ctrl+S",
289 "*fileMenu.includeFile.accelerator: Alt<Key>i",
290 "*fileMenu.includeFile.acceleratorText: Alt+I",
291 "*fileMenu.print.accelerator: Ctrl<Key>p",
292 "*fileMenu.print.acceleratorText: Ctrl+P",
293 "*fileMenu.exit.accelerator: Ctrl<Key>q",
294 "*fileMenu.exit.acceleratorText: Ctrl+Q",
295 "*editMenu.mnemonic: E",
296 "*editMenu.undo.accelerator: Ctrl<Key>z",
297 "*editMenu.undo.acceleratorText: Ctrl+Z",
298 "*editMenu.redo.accelerator: Shift Ctrl<Key>z",
299 "*editMenu.redo.acceleratorText: Shift+Ctrl+Z",
300
301
302
303 "*editMenu.cut.acceleratorText: Ctrl+X",
304 "*editMenu.copy.acceleratorText: Ctrl+C",
305 "*editMenu.paste.acceleratorText: Ctrl+V",
306 "*editMenu.pasteColumn.accelerator: Shift Ctrl<Key>v",
307 "*editMenu.pasteColumn.acceleratorText: Ctrl+Shift+V",
308 "*editMenu.delete.acceleratorText: Del",
309 "*editMenu.selectAll.accelerator: Ctrl<Key>a",
310 "*editMenu.selectAll.acceleratorText: Ctrl+A",
311 "*editMenu.shiftLeft.accelerator: Ctrl<Key>9",
312 "*editMenu.shiftLeft.acceleratorText: [Shift]Ctrl+9",
313 "*editMenu.shiftLeftShift.accelerator: Shift Ctrl<Key>9",
314 "*editMenu.shiftRight.accelerator: Ctrl<Key>0",
315 "*editMenu.shiftRight.acceleratorText: [Shift]Ctrl+0",
316 "*editMenu.shiftRightShift.accelerator: Shift Ctrl<Key>0",
317 "*editMenu.upperCase.accelerator: Ctrl<Key>6",
318 "*editMenu.upperCase.acceleratorText: Ctrl+6",
319 "*editMenu.lowerCase.accelerator: Shift Ctrl<Key>6",
320 "*editMenu.lowerCase.acceleratorText: Shift+Ctrl+6",
321 "*editMenu.fillParagraph.accelerator: Ctrl<Key>j",
322 "*editMenu.fillParagraph.acceleratorText: Ctrl+J",
323 "*editMenu.insertFormFeed.accelerator: Alt Ctrl<Key>l",
324 "*editMenu.insertFormFeed.acceleratorText: Alt+Ctrl+L",
325 "*editMenu.insertCtrlCode.accelerator: Alt Ctrl<Key>i",
326 "*editMenu.insertCtrlCode.acceleratorText: Alt+Ctrl+I",
327 "*editMenu.insertUnicode.accelerator: Alt Ctrl<Key>u",
328 "*editMenu.insertUnicode.acceleratorText: Alt+Ctrl+U",
329 "*searchMenu.mnemonic: S",
330 "*searchMenu.find.accelerator: Ctrl<Key>f",
331 "*searchMenu.find.acceleratorText: [Shift]Ctrl+F",
332 "*searchMenu.findShift.accelerator: Shift Ctrl<Key>f",
333 "*searchMenu.findAgain.accelerator: Ctrl<Key>g",
334 "*searchMenu.findAgain.acceleratorText: [Shift]Ctrl+G",
335 "*searchMenu.findAgainShift.accelerator: Shift Ctrl<Key>g",
336 "*searchMenu.findSelection.accelerator: Ctrl<Key>h",
337 "*searchMenu.findSelection.acceleratorText: [Shift]Ctrl+H",
338 "*searchMenu.findSelectionShift.accelerator: Shift Ctrl<Key>h",
339 "*searchMenu.findIncremental.accelerator: Ctrl<Key>i",
340 "*searchMenu.findIncrementalShift.accelerator: Shift Ctrl<Key>i",
341 "*searchMenu.findIncremental.acceleratorText: [Shift]Ctrl+I",
342 "*searchMenu.replace.accelerator: Ctrl<Key>r",
343 "*searchMenu.replace.acceleratorText: [Shift]Ctrl+R",
344 "*searchMenu.replaceShift.accelerator: Shift Ctrl<Key>r",
345 "*searchMenu.findReplace.accelerator: Ctrl<Key>r",
346 "*searchMenu.findReplace.acceleratorText: [Shift]Ctrl+R",
347 "*searchMenu.findReplaceShift.accelerator: Shift Ctrl<Key>r",
348 "*searchMenu.replaceFindAgain.accelerator: Ctrl<Key>t",
349 "*searchMenu.replaceFindAgain.acceleratorText: [Shift]Ctrl+T",
350 "*searchMenu.replaceFindAgainShift.accelerator: Shift Ctrl<Key>t",
351 "*searchMenu.replaceAgain.accelerator: Alt<Key>t",
352 "*searchMenu.replaceAgain.acceleratorText: [Shift]Alt+T",
353 "*searchMenu.replaceAgainShift.accelerator: Shift Alt<Key>t",
354 "*searchMenu.gotoLineNumber.accelerator: Ctrl<Key>l",
355 "*searchMenu.gotoLineNumber.acceleratorText: Ctrl+L",
356 "*searchMenu.gotoSelected.accelerator: Ctrl<Key>e",
357 "*searchMenu.gotoSelected.acceleratorText: Ctrl+E",
358 "*searchMenu.mark.accelerator: Alt<Key>m",
359 "*searchMenu.mark.acceleratorText: Alt+M a-z",
360 "*searchMenu.gotoMark.accelerator: Alt<Key>g",
361 "*searchMenu.gotoMark.acceleratorText: [Shift]Alt+G a-z",
362 "*searchMenu.gotoMarkShift.accelerator: Shift Alt<Key>g",
363 "*searchMenu.gotoMatching.accelerator: Ctrl<Key>m",
364 "*searchMenu.gotoMatching.acceleratorText: [Shift]Ctrl+M",
365 "*searchMenu.gotoMatchingShift.accelerator: Shift Ctrl<Key>m",
366 "*searchMenu.findDefinition.accelerator: Ctrl<Key>d",
367 "*searchMenu.findDefinition.acceleratorText: Ctrl+D",
368 "*searchMenu.showCalltip.accelerator: Ctrl<Key>apostrophe",
369 "*searchMenu.showCalltip.acceleratorText: Ctrl+''",
370 "*preferencesMenu.mnemonic: P",
371 "*preferencesMenu.statisticsLine.accelerator: Alt<Key>a",
372 "*preferencesMenu.statisticsLine.acceleratorText: Alt+A",
373 "*preferencesMenu.overtype.acceleratorText: Insert",
374 "*shellMenu.mnemonic: l",
375 "*shellMenu.filterSelection.accelerator: Alt<Key>r",
376 "*shellMenu.filterSelection.acceleratorText: Alt+R",
377 "*shellMenu.executeCommand.accelerator: Alt<Key>x",
378 "*shellMenu.executeCommand.acceleratorText: Alt+X",
379 "*shellMenu.executeCommandLine.accelerator: Ctrl<Key>KP_Enter",
380 "*shellMenu.executeCommandLine.acceleratorText: Ctrl+KP Enter",
381 "*shellMenu.cancelShellCommand.accelerator: Ctrl<Key>period",
382 "*shellMenu.cancelShellCommand.acceleratorText: Ctrl+.",
383 "*macroMenu.mnemonic: c",
384 "*macroMenu.learnKeystrokes.accelerator: Alt<Key>k",
385 "*macroMenu.learnKeystrokes.acceleratorText: Alt+K",
386 "*macroMenu.finishLearn.accelerator: Alt<Key>k",
387 "*macroMenu.finishLearn.acceleratorText: Alt+K",
388 "*macroMenu.cancelLearn.accelerator: Ctrl<Key>period",
389 "*macroMenu.cancelLearn.acceleratorText: Ctrl+.",
390 "*macroMenu.replayKeystrokes.accelerator: Ctrl<Key>k",
391 "*macroMenu.replayKeystrokes.acceleratorText: Ctrl+K",
392 "*macroMenu.repeat.accelerator: Ctrl<Key>comma",
393 "*macroMenu.repeat.acceleratorText: Ctrl+,",
394 "*windowsMenu.mnemonic: W",
395 "*windowsMenu.splitPane.accelerator: Ctrl<Key>2",
396 "*windowsMenu.splitPane.acceleratorText: Ctrl+2",
397 "*windowsMenu.closePane.accelerator: Ctrl<Key>1",
398 "*windowsMenu.closePane.acceleratorText: Ctrl+1",
399 "*helpMenu.mnemonic: H",
400 "?.help.helpForm.sw.helpText*baseTranslations: #override\
401 <Key>Tab:help-focus-buttons()\\n\
402 <Key>Return:help-button-action(\"close\")\\n\
403 Ctrl<Key>F:help-button-action(\"find\")\\n\
404 Ctrl<Key>G:help-button-action(\"findAgain\")\\n\
405 <KeyPress>osfCancel:help-button-action(\"close\")\\n\
406 ~Meta~Ctrl~Shift<Btn1Down>:\
407 grab-focus() help-hyperlink()\\n\
408 ~Meta~Ctrl~Shift<Btn1Up>:\
409 help-hyperlink(\"current\", \"process-cancel\", \"extend-end\")\\n\
410 ~Meta~Ctrl~Shift<Btn2Down>:\
411 process-bdrag() help-hyperlink()\\n\
412 ~Meta~Ctrl~Shift<Btn2Up>:\
413 help-hyperlink(\"new\", \"process-cancel\", \"copy-to\")",
414 NULL
415 };
416
417 static const char cmdLineHelp[] =
418 "Usage: xnedit [-read] [-create] [-line n | +n] [-server] [-do command]\n\
419 [-tags file] [-tabs n] [-wrap] [-nowrap] [-autowrap]\n\
420 [-autoindent] [-noautoindent] [-autosave] [-noautosave]\n\
421 [-lm languagemode] [-rows n] [-columns n] [-font font]\n\
422 [-geometry geometry] [-iconic] [-noiconic] [-svrname name]\n\
423 [-display [host]:server[.screen] [-xrm resourcestring]\n\
424 [-import file] [-background color] [-foreground color]\n\
425 [-tabbed] [-untabbed] [-group] [-bgrun] [-V|-version]\n\
426 [-h|-help] [--] [file...]\n";
427
428
429
430
431
432 static char *XNEditAppName =
"nedit";
433
434 char* GetAppName(
void)
435 {
436 return XNEditAppName;
437 }
438
439 int main(
int argc,
char **argv)
440 {
441 int i, lineNum, nRead, fileSpecified =
FALSE, editFlags =
CREATE;
442 int gotoLine = False, macroFileRead = False, opts = True;
443 int iconic=False, tabbed = -
1, group =
0, isTabbed;
444 char *toDoCommand =
NULL, *geometry =
NULL, *langMode =
NULL;
445 char filename[
MAXPATHLEN], pathname[
MAXPATHLEN];
446 XtAppContext context;
447 XrmDatabase prefDB;
448 WindowInfo *window =
NULL, *lastFile =
NULL;
449 static const char *protectedKeywords[] = {
"-iconic",
"-icon",
"-geometry",
450 "-g",
"-rv",
"-reverse",
"-bd",
"-bordercolor",
"-borderwidth",
451 "-bw",
"-title",
NULL};
452 unsigned char* invalidBindings =
NULL;
453
454
455 enum MotifStability stability = GetMotifStability();
456
457 char *appNameVar = getenv(
"XNEDIT_APPNAME");
458 if(appNameVar) {
459 XNEditAppName = appNameVar;
460 }
461
462 if (stability == MotifKnownBad) {
463 fputs(
"xnedit: WARNING: This version of XNEdit is built incorrectly, and will be unstable.\n",
464 stderr);
465 #ifndef BUILD_BROKEN_NEDIT
466
467
468 exit(
EXIT_FAILURE);
469 #endif
470 }
471
472
473 ArgV0 = argv[
0];
474
475 for (i=
1; i<argc; i++) {
476 if(opts && !strcmp(argv[
1],
"--")) {
477 opts = False;
478 continue;
479 }
else if (opts && !strcmp(argv[i],
"-bgrun")) {
480 BackgroundRun = True;
481 break;
482 }
483 }
484 opts = True;
485
486 int retpipe[
2];
487 pid_t pid = -
1;
488 if(BackgroundRun) {
489 if(pipe(retpipe)) {
490 perror(
"pipe");
491 fprintf(stderr,
"Abort.\n");
492 return 1;
493 }
494 pid = fork();
495 if(pid <
0) {
496 perror(
"fork");
497 fprintf(stderr,
"Abort.\n");
498 return 1;
499 }
else if(pid >
0) {
500 int ret =
0;
501 if(read(retpipe[
0], &ret,
sizeof(
int)) !=
sizeof(
int)) {
502 return 1;
503 }
504 return ret;
505 }
506 }
507
508
509
510
511 XtSetLanguageProc(
NULL, neditLanguageProc,
NULL);
512
513
514 XtToolkitInitialize();
515 context = XtCreateApplicationContext();
516
517
518 SuppressPassiveGrabWarnings();
519
520
521 XtAppSetWarningHandler(context, noWarningFilter);
522
523
524 XtAppSetFallbackResources(context, fallbackResources);
525
526 #if XmVersion >=
1002
527
528 XmRepTypeInstallTearOffModelConverter();
529 #endif
530
531 #ifdef __EMX__
532
533 _wildcard(&argc, &argv);
534 #endif
535
536
537 prefDB = CreateNEditPrefDB(&argc, argv);
538
539
540
541
542
543
544 maskArgvKeywords(argc, argv, protectedKeywords);
545
546
547
548
549
550
551
552
553
554
555
556
557
558 putenv(
"XLIB_SKIP_ARGB_VISUALS=1");
559 TheDisplay = XtOpenDisplay (context,
NULL,
APP_NAME,
APP_CLASS,
560 NULL,
0, &argc, argv);
561 unmaskArgvKeywords(argc, argv, protectedKeywords);
562 if (!TheDisplay) {
563
564 for (i =
1; i < argc && strcmp(argv[i],
"--"); i++)
565 {
566 if (
0 == strcmp(argv[i],
"-V") ||
0 == strcmp(argv[i],
"-version"))
567 {
568 PrintVersion();
569 exit(
EXIT_SUCCESS);
570 }
571 }
572 fputs (
"XNEdit: Can''t open display\n", stderr);
573 exit(
EXIT_FAILURE);
574 }
575
576 defaultResourceDB = XtScreenDatabase(DefaultScreenOfDisplay(TheDisplay));
577
578
579 XdndInit(TheDisplay, context, dndOpenFileCB,
NULL);
580
581
582 fixupBrokenXKeysymDB();
583 patchResourcesForVisual();
584 patchResourcesForKDEbug();
585
586
587 InitMacroGlobals();
588 RegisterMacroSubroutines();
589
590
591
592
593
594 TextWidgetClassInit(TheDisplay,
NEDIT_XFT_FIXED_FONT ":size=11");
595
596
597
598 RestoreNEditPrefs(prefDB, XtDatabase(TheDisplay));
599
600
601
602 invalidBindings = sanitizeVirtualKeyBindings();
603
604
605
606
607 TheAppShell = CreateShellWithBestVis(
APP_NAME,
608 APP_CLASS,
609 applicationShellWidgetClass,
610 TheDisplay,
611 NULL,
612 0);
613
614
615 restoreInsaneVirtualKeyBindings(invalidBindings);
616
617 XtSetMappedWhenManaged(TheAppShell, False);
618 XtRealizeWidget(TheAppShell);
619
620 #ifndef NO_SESSION_RESTART
621 AttachSessionMgrHandler(TheAppShell);
622 #endif
623
624
625 LoadPrintPreferences(XtDatabase(TheDisplay),
APP_NAME,
APP_CLASS, True);
626 SetDeleteRemap(GetPrefMapDelete());
627 SetPointerCenteredDialogs(GetPrefRepositionDialogs());
628
629
630 InstallMenuActions(context);
631
632
633 InstallHelpLinkActions(context);
634
635
636 InstallMouseWheelActions(context);
637
638
639 SetREDefaultWordDelimiters(GetPrefDelimiters());
640
641
642
643 ReadNEditDB();
644
645
646
647 ReadSearchHistory();
648
649
650
651
652 for (i=
1; i<argc; i++) {
653 if(!strcmp(argv[i],
"--")) {
654 break;
655 }
else if (!strcmp(argv[i],
"-import")) {
656 nextArg(argc, argv, &i);
657 ImportPrefFile(argv[i], False);
658 }
else if (!strcmp(argv[i],
"-importold")) {
659 nextArg(argc, argv, &i);
660 ImportPrefFile(argv[i], True);
661 }
662 }
663
664
665
666
667 if (*GetPrefTagFile() !=
'\0') {
668 AddTagsFile(GetPrefTagFile(),
TAG);
669 }
670
671 if (strcmp(GetPrefServerName(),
"") !=
0) {
672 IsServer = True;
673 }
674
675
676
677
678 fileSpecified =
FALSE;
679 for (i=
1; i<argc; i++) {
680 if (opts && !strcmp(argv[i],
"--")) {
681 opts = False;
682 continue;
683 }
else if (opts && !strcmp(argv[i],
"-tags")) {
684 nextArg(argc, argv, &i);
685 if (!AddTagsFile(argv[i],
TAG))
686 fprintf(stderr,
"XNEdit: Unable to load tags file\n");
687 }
else if (opts && !strcmp(argv[i],
"-do")) {
688 nextArg(argc, argv, &i);
689 if (checkDoMacroArg(argv[i]))
690 toDoCommand = argv[i];
691 }
else if (opts && !strcmp(argv[i],
"-read")) {
692 editFlags |=
PREF_READ_ONLY;
693 }
else if (opts && !strcmp(argv[i],
"-create")) {
694 editFlags |=
SUPPRESS_CREATE_WARN;
695 }
else if (opts && !strcmp(argv[i],
"-tabbed")) {
696 tabbed =
1;
697 group =
0;
698 }
else if (opts && !strcmp(argv[i],
"-untabbed")) {
699 tabbed =
0;
700 group =
0;
701 }
else if (opts && !strcmp(argv[i],
"-group")) {
702 group =
2;
703 }
else if (opts && !strcmp(argv[i],
"-line")) {
704 nextArg(argc, argv, &i);
705 nRead = sscanf(argv[i],
"%d", &lineNum);
706 if (nRead !=
1)
707 fprintf(stderr,
"XNEdit: argument to line should be a number\n");
708 else
709 gotoLine = True;
710 }
else if (opts && (*argv[i] ==
'+')) {
711 nRead = sscanf((argv[i]+
1),
"%d", &lineNum);
712 if (nRead !=
1)
713 fprintf(stderr,
"XNEdit: argument to + should be a number\n");
714 else
715 gotoLine = True;
716 }
else if (opts && !strcmp(argv[i],
"-server")) {
717 IsServer = True;
718 }
else if (opts && !strcmp(argv[i],
"-bgrun")) {
719
720 }
else if (opts && !strcmp(argv[i],
"-xwarn")) {
721 XtAppSetWarningHandler(context, showWarningFilter);
722 }
else if (opts && (!strcmp(argv[i],
"-iconic") ||
723 !strcmp(argv[i],
"-icon"))) {
724 iconic = True;
725 }
else if (opts && !strcmp(argv[i],
"-noiconic")) {
726 iconic = False;
727 }
else if (opts && (!strcmp(argv[i],
"-geometry") ||
728 !strcmp(argv[i],
"-g"))) {
729 nextArg(argc, argv, &i);
730 geometry = argv[i];
731 }
else if (opts && !strcmp(argv[i],
"-lm")) {
732 nextArg(argc, argv, &i);
733 langMode = argv[i];
734 }
else if (opts && !strcmp(argv[i],
"-import")) {
735 nextArg(argc, argv, &i);
736 }
else if (opts && (!strcmp(argv[i],
"-V") ||
737 !strcmp(argv[i],
"-version"))) {
738 PrintVersion();
739 exit(
EXIT_SUCCESS);
740 }
else if (opts && (!strcmp(argv[i],
"-h") ||
741 !strcmp(argv[i],
"-help"))) {
742 fprintf(stderr,
"%s", cmdLineHelp);
743 exit(
EXIT_SUCCESS);
744 }
else if (opts && (*argv[i] ==
'-')) {
745 fprintf(stderr,
"xnedit: Unrecognized option %s\n%s", argv[i],
746 cmdLineHelp);
747 exit(
EXIT_FAILURE);
748 }
else {
749 if (ParseFilename(argv[i], filename, pathname) ==
0 ) {
750
751
752 if (group ==
2) {
753 isTabbed =
0;
754 group =
1;
755 }
else if (group ==
1) {
756 isTabbed =
1;
757 }
else {
758 isTabbed = tabbed==-
1? GetPrefOpenInTab() : tabbed;
759 }
760
761
762 size_t pathlen = strlen(pathname);
763 size_t namelen = strlen(filename);
764 char *fullpath = NEditMalloc(pathlen + namelen +
1);
765 memcpy(fullpath, pathname, pathlen);
766 memcpy(fullpath+pathlen, filename, namelen);
767 fullpath[pathlen+namelen] =
'\0';
768 IOFilter *filter = GetFilterForPath(fullpath);
769 const char *filter_name = filter ? filter->name :
NULL;
770 NEditFree(fullpath);
771
772
773
774
775
776
777
778 window = EditExistingFile(WindowList, filename, pathname,
NULL,
779 filter_name, editFlags, geometry, iconic, langMode, isTabbed,
780 True);
781 fileSpecified =
TRUE;
782 if (window) {
783 CleanUpTabBarExposeQueue(window);
784
785
786 if (lastFile && window->shell != lastFile->shell) {
787 CleanUpTabBarExposeQueue(lastFile);
788 RaiseDocument(lastFile);
789 }
790
791 if (!macroFileRead) {
792 ReadMacroInitFile(WindowList);
793 macroFileRead = True;
794 }
795 if (gotoLine)
796 SelectNumberedLine(window, lineNum);
797 if (toDoCommand !=
NULL) {
798 DoMacro(window, toDoCommand,
"-do macro");
799 toDoCommand =
NULL;
800 if (!IsValidWindow(window))
801 window =
NULL;
802 if (lastFile && !IsValidWindow(lastFile))
803 lastFile =
NULL;
804 }
805 }
806
807
808 if (window)
809 lastFile = window;
810 }
else {
811 fprintf(stderr,
"xnedit: file name too long: %s\n", argv[i]);
812 }
813
814
815 gotoLine = False;
816 }
817 }
818
819
820 if (lastFile) {
821 CleanUpTabBarExposeQueue(lastFile);
822 RaiseDocument(lastFile);
823 }
824 CheckCloseDim();
825
826
827 if (!fileSpecified) {
828 EditNewFile(
NULL, geometry, iconic, langMode,
NULL);
829 ReadMacroInitFile(WindowList);
830 CheckCloseDim();
831 if (toDoCommand !=
NULL)
832 DoMacro(WindowList, toDoCommand,
"-do macro");
833 }
834
835
836 AddLastCommandActionHook(context);
837
838
839 if (IsServer)
840 InitServerCommunication();
841
842 if (BackgroundRun) {
843 if(pid !=
0) {
844
845 close(
0);
846 close(
1);
847 close(
2);
848 }
849 int ret =
0;
850 write(retpipe[
1], &ret,
sizeof(
int));
851 close(retpipe[
0]);
852 close(retpipe[
1]);
853 }
854
855
856 if (IsServer)
857 ServerMainLoop(context);
858 else
859 XtAppMainLoop(context);
860
861
862 return EXIT_SUCCESS;
863 }
864
865 static void nextArg(
int argc,
char **argv,
int *argIndex)
866 {
867 if (*argIndex +
1 >= argc) {
868 fprintf(stderr,
"XNEdit: %s requires an argument\n%s", argv[*argIndex],
869 cmdLineHelp);
870 exit(
EXIT_FAILURE);
871 }
872 (*argIndex)++;
873 }
874
875
876
877
878 static int checkDoMacroArg(
const char *macro)
879 {
880 Program *prog;
881 char *errMsg, *stoppedAt, *tMacro;
882 int macroLen;
883
884
885
886 macroLen = strlen(macro);
887 tMacro = (
char*)NEditMalloc(strlen(macro)+
2);
888 strncpy(tMacro, macro, macroLen);
889 tMacro[macroLen] =
'\n';
890 tMacro[macroLen+
1] =
'\0';
891
892
893 prog = ParseMacro(tMacro, &errMsg, &stoppedAt);
894 NEditFree(tMacro);
895 if (prog ==
NULL) {
896 ParseError(
NULL, tMacro, stoppedAt,
"argument to -do", errMsg);
897 return False;
898 }
899 FreeProgram(prog);
900 return True;
901 }
902
903
904
905
906
907
908
909
910
911
912 static void maskArgvKeywords(
int argc,
char **argv,
const char **maskArgs)
913 {
914 int i, k;
915
916 for (i=
1; i<argc; i++)
917 for (k=
0; maskArgs[k]!=
NULL; k++)
918 if (!strcmp(argv[i], maskArgs[k]))
919 argv[i][
0] =
' ';
920 }
921
922
923 static void unmaskArgvKeywords(
int argc,
char **argv,
const char **maskArgs)
924 {
925 int i, k;
926
927 for (i=
1; i<argc; i++)
928 for (k=
0; maskArgs[k]!=
NULL; k++)
929 if (argv[i][
0]==
' ' && !strcmp(&argv[i][
1], &maskArgs[k][
1]))
930 argv[i][
0] =
'-';
931 }
932
933
934
935
936
937
938
939 static void fixupBrokenXKeysymDB(
void)
940 {
941 const char *keysym = getenv(
"XKEYSYMDB");
942
943 if (keysym !=
NULL && access(keysym,
F_OK) !=
0)
944 putenv(
"XKEYSYMDB");
945 }
946
947
948
949
950
951
952
953
954 static void patchResourcesForVisual(
void)
955 {
956 Cardinal i;
957 Visual *visual;
958 int depth;
959 Colormap map;
960 Boolean usingDefaultVisual;
961 XrmDatabase db;
962
963 if (!TheDisplay)
964 return;
965
966 db = XtDatabase(TheDisplay);
967
968 usingDefaultVisual = FindBestVisual(TheDisplay,
969 APP_NAME,
970 APP_CLASS,
971 &visual,
972 &depth,
973 &map);
974
975 if (!usingDefaultVisual)
976 {
977 #ifndef LESSTIF_VERSION
978
979
980
981
982
983
984
985
986
987
988
989 XrmValue value;
990 value.addr = (XPointer)&visual;
991 value.size =
sizeof(visual);
992 XrmPutResource(&db,
"*visual",
"Visual", &value);
993 value.addr = (XPointer)↦
994 value.size =
sizeof(map);
995 XrmPutResource(&db,
"*colormap",
"Colormap", &value);
996 value.addr = (XPointer)&depth;
997 value.size =
sizeof(depth);
998 XrmPutResource(&db,
"*depth",
"Int", &value);
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012 #endif
1013
1014 for (i =
1; i < XtNumber(fallbackResources); ++i)
1015 {
1016 Cardinal resIndex = i -
1;
1017
1018 if (strstr(fallbackResources[resIndex],
"*background:") ||
1019 strstr(fallbackResources[resIndex],
"*foreground:"))
1020 {
1021
1022
1023 char buf[
1024];
1024 snprintf(buf,
2,
"*%s",
APP_NAME);
1025 strcat(buf, fallbackResources[resIndex]);
1026 XrmPutLineResource(&db, buf);
1027 }
1028 }
1029 }
1030 }
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043 static void patchResourcesForKDEbug(
void)
1044 {
1045
1046
1047
1048 static const char* buggyResources[][
3] = {
1049 {
"*fontList",
"FONTLIST",
NEDIT_DEFAULT_FONT },
1050 {
"*XmText.background",
"BACKGROUND",
NEDIT_DEFAULT_TEXT_BG },
1051 {
"*XmText.foreground",
"FOREGROUND",
NEDIT_DEFAULT_FG },
1052 {
"*XmTextField.background",
"BACKGROUND",
NEDIT_DEFAULT_TEXT_BG },
1053 {
"*XmTextField.foreground",
"FOREGROUND",
NEDIT_DEFAULT_FG },
1054 {
"*XmList.background",
"BACKGROUND",
NEDIT_DEFAULT_TEXT_BG },
1055 {
"*XmList.foreground",
"FOREGROUND",
NEDIT_DEFAULT_FG },
1056 {
"*helpText.background",
"BACKGROUND",
NEDIT_DEFAULT_HELP_BG },
1057 {
"*helpText.foreground",
"FOREGROUND",
NEDIT_DEFAULT_HELP_FG },
1058 {
"*background",
"BACKGROUND",
NEDIT_DEFAULT_BG },
1059 {
"*foreground",
"FOREGROUND",
NEDIT_DEFAULT_FG, },
1060 {
"*selectColor",
"BACKGROUND",
NEDIT_DEFAULT_SEL_BG },
1061 {
"*highlightColor",
"BACKGROUND",
NEDIT_DEFAULT_HI_BG },
1062 {
"*text.background",
"WINDOW_BACKGROUND",
NEDIT_DEFAULT_TEXT_BG },
1063 {
"*text.foreground",
"WINDOW_FOREGROUND",
NEDIT_DEFAULT_FG },
1064 {
"*text.selectBackground",
"SELECT_BACKGROUND",
NEDIT_DEFAULT_SEL_BG },
1065 {
"*text.selectForeground",
"SELECT_FOREGROUND",
NEDIT_DEFAULT_SEL_FG },
1066 {
"*text.cursorForeground",
"WINDOW_FOREGROUND",
NEDIT_DEFAULT_CURSOR_FG},
1067
1068
1069
1070
1071 {
"*statsLine.background",
"BACKGROUND",
NEDIT_DEFAULT_BG },
1072 {
"*statsLine.foreground",
"FOREGROUND",
NEDIT_DEFAULT_FG },
1073 {
NULL,
NULL,
NULL } };
1074 XrmDatabase db;
1075 int i;
1076
1077 if (!TheDisplay)
1078 return;
1079
1080 db = XtDatabase(TheDisplay);
1081
1082 i =
0;
1083 while (buggyResources[i][
0])
1084 {
1085 const char* resource = buggyResources[i][
0];
1086 const char* buggyValue = buggyResources[i][
1];
1087 const char* defaultValue = buggyResources[i][
2];
1088 char name[
128];
1089 char class[
128];
1090 char* type;
1091 XrmValue resValue;
1092
1093 snprintf(name,
128,
"%s%s",
APP_NAME, resource);
1094 snprintf(class,
128,
"%s%s",
APP_CLASS, resource);
1095
1096 if (XrmGetResource(db, name, class, &type, &resValue) &&
1097 !strcmp(type, XmRString))
1098 {
1099
1100 if (!strcmp(resValue.addr, buggyValue))
1101 {
1102 XrmPutStringResource(&db, &name[
0], (
char*)defaultValue);
1103 }
1104 }
1105 ++i;
1106 }
1107 }
1108
1109 int XNEditDefaultCharsetIsUTF8(
void)
1110 {
1111 static int defaultCharsetIsUtf8 = -
1;
1112 if(defaultCharsetIsUtf8 == -
1) {
1113 char *l = nl_langinfo(
CODESET);
1114 defaultCharsetIsUtf8 = !strcmp(l,
"UTF-8") ?
1 :
0;
1115 }
1116 return defaultCharsetIsUtf8;
1117 }
1118
1119
1120
1121
1122
1123
1124 static String neditLanguageProc(Display *dpy, String xnl, XtPointer closure)
1125 {
1126
1127
1128
1129
1130
1131 if (! setlocale(
LC_ALL, xnl)) {
1132 XtWarning(
"locale not supported by C library, locale unchanged");
1133 }
1134
1135
1136
1137 if (! XSupportsLocale()) {
1138 XtWarning(
"locale not supported by Xlib, locale set to C");
1139 setlocale(
LC_ALL,
"C");
1140 }
1141 if (! XSetLocaleModifiers(
""))
1142 XtWarning(
"X locale modifiers not supported, using default");
1143
1144 return setlocale(
LC_ALL,
NULL);
1145 }
1146
1147 static int sortAlphabetical(
const void* k1,
const void* k2)
1148 {
1149 const char* key1 = *(
const char**)k1;
1150 const char* key2 = *(
const char**)k2;
1151 return strcmp(key1, key2);
1152 }
1153
1154
1155
1156
1157
1158 static int virtKeyBindingsAreInvalid(
const unsigned char* bindings)
1159 {
1160 int maxCount =
1, i, count;
1161 const char *pos = (
const char*)bindings;
1162 char *copy;
1163 char *pos2, *pos3;
1164 char **keys;
1165
1166
1167
1168
1169
1170 while ((pos = strstr(pos,
"\n")))
1171 {
1172 ++pos;
1173 ++maxCount;
1174 }
1175
1176 if (maxCount ==
1)
1177 return False;
1178
1179 keys = (
char**)NEditMalloc(maxCount*
sizeof(
char*));
1180 copy = NEditStrdup((
const char*)bindings);
1181 i =
0;
1182 pos2 = copy;
1183
1184 count =
0;
1185 while (i<maxCount && pos2 && *pos2)
1186 {
1187 while (isspace((
int) *pos2) || *pos2 ==
'\n') ++pos2;
1188
1189 if (*pos2 ==
'!')
1190 {
1191 pos2 = strstr(pos2,
"\n");
1192 continue;
1193 }
1194
1195 if (*pos2)
1196 {
1197 keys[i++] = pos2;
1198 ++count;
1199 pos3 = strstr(pos2,
":");
1200 if (pos3)
1201 {
1202 *pos3++ =
0;
1203 pos2 = pos3;
1204 }
1205 pos2 = strstr(pos2,
"\n");
1206 }
1207 }
1208
1209 if (count <=
1)
1210 {
1211 free(keys);
1212 NEditFree(copy);
1213 return False;
1214 }
1215
1216
1217 qsort((
void*)keys, count,
sizeof(
const char*), sortAlphabetical);
1218 for (i=
1; i<count; ++i)
1219 {
1220 if (!strcmp(keys[i-
1], keys[i]))
1221 {
1222
1223 free(keys);
1224 NEditFree(copy);
1225 return True;
1226 }
1227 }
1228 free(keys);
1229 NEditFree(copy);
1230 return False;
1231 }
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243 static Atom virtKeyAtom;
1244
1245 static unsigned char* sanitizeVirtualKeyBindings(
void)
1246 {
1247 int overrideBindings = GetPrefOverrideVirtKeyBindings();
1248 Window rootWindow;
1249 const char *virtKeyPropName =
"_MOTIF_DEFAULT_BINDINGS";
1250 Atom dummyAtom;
1251 int getFmt;
1252 unsigned long dummyULong, nItems;
1253 unsigned char *insaneVirtKeyBindings =
NULL;
1254
1255 if (overrideBindings ==
VIRT_KEY_OVERRIDE_NEVER)
return NULL;
1256
1257 virtKeyAtom = XInternAtom(TheDisplay, virtKeyPropName, False);
1258 rootWindow = RootWindow(TheDisplay, DefaultScreen(TheDisplay));
1259
1260
1261 if (XGetWindowProperty(TheDisplay, rootWindow, virtKeyAtom,
0,
INT_MAX,
1262 True,
XA_STRING, &dummyAtom, &getFmt, &nItems,
1263 &dummyULong, &insaneVirtKeyBindings) != Success
1264 || nItems ==
0)
1265 {
1266 return NULL;
1267 }
1268
1269 if (overrideBindings ==
VIRT_KEY_OVERRIDE_AUTO)
1270 {
1271 if (!virtKeyBindingsAreInvalid(insaneVirtKeyBindings))
1272 {
1273
1274 XChangeProperty(TheDisplay, rootWindow, virtKeyAtom,
XA_STRING,
8,
1275 PropModeReplace, insaneVirtKeyBindings,
1276 strlen((
const char*)insaneVirtKeyBindings));
1277 XFree((
char*)insaneVirtKeyBindings);
1278 return NULL;
1279 }
1280 }
1281 return insaneVirtKeyBindings;
1282 }
1283
1284
1285
1286
1287
1288 static void restoreInsaneVirtualKeyBindings(
unsigned char *insaneVirtKeyBindings)
1289 {
1290 if (insaneVirtKeyBindings)
1291 {
1292 Window rootWindow = RootWindow(TheDisplay, DefaultScreen(TheDisplay));
1293
1294
1295 XChangeProperty(TheDisplay, rootWindow, virtKeyAtom,
XA_STRING,
8,
1296 PropModeReplace, insaneVirtKeyBindings,
1297 strlen((
const char*)insaneVirtKeyBindings));
1298 XFree((
char*)insaneVirtKeyBindings);
1299 }
1300 }
1301
1302
1303
1304
1305
1306 static void showWarningFilter(String message)
1307 {
1308 const char* bogusMessages[] = {
1309 #ifdef LESSTIF_VERSION
1310 "XmFontListCreate() is an obsolete function!",
1311 "No type converter registered for ''String'' to ''PathMode'' conversion.",
1312 "XtRemoveGrab asked to remove a widget not on the list",
1313 #endif
1314 NULL
1315 };
1316 const char **bogusMessage = &bogusMessages[
0];
1317
1318 while (*bogusMessage) {
1319 size_t bogusLen = strlen(*bogusMessage);
1320 if (strncmp(message, *bogusMessage, bogusLen) ==
0) {
1321 #ifdef DEBUG_LESSTIF_WARNINGS
1322
1323 fprintf(stderr,
"[SUPPRESSED] %s\n", message);
1324 #endif
1325 return;
1326 }
1327 ++bogusMessage;
1328 }
1329
1330
1331 fprintf(stderr,
"%s\n", message);
1332 }
1333
1334 static void noWarningFilter(String message)
1335 {
1336 return;
1337 }
1338
1339 static void dndOpenFileCB(Widget w, XtPointer value, XtPointer data) {
1340 char *urilist = value;
1341
1342 size_t len = strlen(urilist);
1343
1344 size_t start =
0;
1345 if(len >
7 && !memcmp(urilist,
"file://",
7)) {
1346 start =
7;
1347 }
1348
1349 int err =
0;
1350
1351
1352 char *path = NEditMalloc(len +
1);
1353 int k =
0;
1354 for(
int i=start;i<len;i++) {
1355 char c = urilist[i];
1356 if(c ==
'%') {
1357 if(i +
2 < len) {
1358 char code[
3];
1359 code[
0] = urilist[i+
1];
1360 code[
1] = urilist[i+
2];
1361 code[
2] =
'\0';
1362
1363 errno =
0;
1364 char *end =
NULL;
1365 int ascii = (
int)strtol(code, &end,
16);
1366 if(errno ==
0 && end == &code[
2]) {
1367 path[k] = ascii;
1368 i +=
2;
1369 }
else {
1370 err =
1;
1371 break;
1372 }
1373 }
else {
1374 err =
1;
1375 break;
1376 }
1377 }
else if(c ==
'\n' || c ==
'\r') {
1378 break;
1379 }
else {
1380 path[k] = c;
1381 }
1382
1383 k++;
1384 }
1385 path[k] =
'\0';
1386
1387
1388 if(err ==
0) {
1389 char *params[
2];
1390 params[
0] = path;
1391 params[
1] =
NULL;
1392 XtCallActionProc(w,
"open",
NULL, params,
1);
1393 }
else {
1394 fprintf(stderr,
"dnd open file: url decode error\n");
1395 }
1396
1397 NEditFree(path);
1398 }
1399
1400 XrmDatabase GetDefaultResourceDB(
void)
1401 {
1402 return defaultResourceDB;
1403 }
1404