void structGuiOptionMenu:: f_addOption (const wchar_t *text) { #if gtk gtk_combo_box_append_text (GTK_COMBO_BOX (d_widget), Melder_peekWcsToUtf8 (text)); #elif motif GuiMenuItem menuItem = Thing_new (GuiMenuItem); menuItem -> d_widget = XtVaCreateManagedWidget (Melder_peekWcsToUtf8 (text), xmToggleButtonWidgetClass, d_widget, NULL); XtAddCallback (menuItem -> d_widget, XmNvalueChangedCallback, cb_optionChanged, (XtPointer) this); Collection_addItem (d_options, menuItem); #endif }
void Graphics_imageFromFile (Graphics me, const wchar_t *relativeFileName, double x1, double x2, double y1, double y2) { if (my screen) { _GraphicsScreen_imageFromFile (static_cast <GraphicsScreen> (me), relativeFileName, x1, x2, y1, y2); } if (my recording) { char *txt_utf8 = Melder_peekWcsToUtf8 (relativeFileName); int length = strlen (txt_utf8) / sizeof (double) + 1; op (IMAGE_FROM_FILE, 5 + length); put (x1); put (x2); put (y1); put (y2); sput (txt_utf8, length) }
void * _Thing_check (I, void *klas, const char *fileName, int line) { Thing me = (structThing*)void_me; /* NOT the macro `iam (Thing);' because that would be recursive. */ if (! me) Melder_fatal ("(_Thing_check:) NULL object passed to a function\n" "in file %.100s at line %d.", fileName, line); Thing_Table table = my methods; while (table != klas && table != NULL) table = table -> _parent; if (! table) Melder_fatal ("(_Thing_check:) Object of wrong class (%.50s) passed to a function\n" "in file %.100s at line %d.", Melder_peekWcsToUtf8 (our _className), fileName, line); return me; }
GuiCheckButton GuiCheckButton_create (GuiForm parent, int left, int right, int top, int bottom, const wchar_t *buttonText, void (*valueChangedCallback) (void *boss, GuiCheckButtonEvent event), void *valueChangedBoss, unsigned long flags) { GuiCheckButton me = Thing_new (GuiCheckButton); my d_shell = parent -> d_shell; my d_parent = parent; my d_valueChangedCallback = valueChangedCallback; my d_valueChangedBoss = valueChangedBoss; #if gtk my d_widget = gtk_check_button_new_with_label (Melder_peekWcsToUtf8 (buttonText)); _GuiObject_setUserData (my d_widget, me); my v_positionInForm (my d_widget, left, right, top, bottom, parent); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (my d_widget), (flags & GuiCheckButton_SET) != 0); if (flags & GuiCheckButton_INSENSITIVE) { my f_setSensitive (false); } g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkCheckButton_destroyCallback), me); my d_valueChangedHandlerId = g_signal_connect (GTK_TOGGLE_BUTTON (my d_widget), "toggled", G_CALLBACK (_GuiGtkCheckButton_valueChangedCallback), me); #elif cocoa #elif win my d_widget = _Gui_initializeWidget (xmToggleButtonWidgetClass, parent -> d_widget, buttonText); _GuiObject_setUserData (my d_widget, me); my d_widget -> isRadioButton = false; my d_widget -> window = CreateWindow (L"button", _GuiWin_expandAmpersands (buttonText), WS_CHILD | BS_AUTOCHECKBOX | WS_CLIPSIBLINGS, my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height, my d_widget -> parent -> window, (HMENU) 1, theGui.instance, NULL); SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget); SetWindowFont (my d_widget -> window, GetStockFont (ANSI_VAR_FONT), FALSE); my v_positionInForm (my d_widget, left, right, top, bottom, parent); if (flags & GuiCheckButton_SET) { Button_SetCheck (my d_widget -> window, BST_CHECKED); } if (flags & GuiCheckButton_INSENSITIVE) { my f_setSensitive (false); } #elif mac my d_widget = _Gui_initializeWidget (xmToggleButtonWidgetClass, parent -> d_widget, buttonText); _GuiObject_setUserData (my d_widget, me); my d_widget -> isRadioButton = false; CreateCheckBoxControl (my d_widget -> macWindow, & my d_widget -> rect, NULL, (flags & GuiCheckButton_SET) != 0, true, & my d_widget -> nat.control.handle); Melder_assert (my d_widget -> nat.control.handle != NULL); SetControlReference (my d_widget -> nat.control.handle, (long) my d_widget); my d_widget -> isControl = true; _GuiNativeControl_setFont (my d_widget, 0, 13); _GuiNativeControl_setTitle (my d_widget); my v_positionInForm (my d_widget, left, right, top, bottom, parent); if (flags & GuiCheckButton_INSENSITIVE) { my f_setSensitive (false); } #endif return me; }
wchar_t * Melder_getenv (const wchar_t *variableName) { #if defined (macintosh) || defined (UNIX) || defined (__MINGW32__) return Melder_peekUtf8ToWcs (getenv (Melder_peekWcsToUtf8 (variableName))); #elif defined (_WIN32) static wchar_t buffer [11] [255]; static int ibuffer = 0; if (++ ibuffer == 11) ibuffer = 0; long n = GetEnvironmentVariableW (variableName, buffer [ibuffer], 255); if (n == ERROR_ENVVAR_NOT_FOUND) return NULL; return & buffer [ibuffer] [0]; #endif }
GuiObject GuiMenuBar_addMenu2 (GuiObject bar, const wchar_t *title, long flags, GuiObject *menuTitle) { GuiObject menu; *menuTitle = gtk_menu_item_new_with_label (Melder_peekWcsToUtf8 (title)); menu = gtk_menu_new (); GtkAccelGroup *ag = (GtkAccelGroup*)(GTK_IS_MENU_BAR (bar) ? g_object_get_data (G_OBJECT (bar), "accel-group") : gtk_menu_get_accel_group (GTK_MENU (bar))); gtk_menu_set_accel_group (GTK_MENU (menu), ag); if (flags & GuiMenu_INSENSITIVE) gtk_widget_set_sensitive (menu, FALSE); gtk_menu_item_set_submenu (GTK_MENU_ITEM (*menuTitle), menu); gtk_menu_shell_append (GTK_MENU_SHELL (bar), *menuTitle); gtk_widget_show (menu); gtk_widget_show (*menuTitle); return menu; }
void structGuiOptionMenu :: f_setValue (int value) { #if gtk gtk_combo_box_set_active (GTK_COMBO_BOX (d_widget), value - 1); #elif cocoa #elif motif for (int i = 1; i <= d_options -> size; i ++) { GuiMenuItem menuItem = static_cast <GuiMenuItem> (d_options -> item [i]); XmToggleButtonSetState (menuItem -> d_widget, i == value, False); if (i == value) { XtVaSetValues (d_xmCascadeButton, XmNlabelString, Melder_peekWcsToUtf8 (menuItem -> d_widget -> name), NULL); } } #endif d_value = value; }
GuiObject GuiMenuBar_addMenu3 (GuiObject parent, const wchar_t *title, long flags, GuiObject *button) { GuiObject menu; menu = gtk_menu_new (); *button = gtk_button_new_with_label (Melder_peekWcsToUtf8 (title)); g_signal_connect_object (G_OBJECT (*button), "event", GTK_SIGNAL_FUNC (button_press), G_OBJECT (menu), G_CONNECT_SWAPPED); g_object_set_data (G_OBJECT (menu), "button", *button); if (flags & GuiMenu_INSENSITIVE) gtk_widget_set_sensitive (menu, FALSE); gtk_menu_attach_to_widget (GTK_MENU (menu), *button, NULL); /* TODO: Free button? */ gtk_container_add (GTK_CONTAINER (parent), *button); gtk_widget_show (menu); gtk_widget_show (*button); return menu; }
static void cb_optionChanged (GuiObject w, XtPointer void_me, XtPointer call) { iam (GuiOptionMenu); (void) call; for (int i = 1; i <= my d_options -> size; i ++) { GuiMenuItem item = static_cast <GuiMenuItem> (my d_options -> item [i]); if (item -> d_widget == w) { XtVaSetValues (my d_xmCascadeButton, XmNlabelString, Melder_peekWcsToUtf8 (item -> d_widget -> name), NULL); XmToggleButtonSetState (item -> d_widget, TRUE, FALSE); if (Melder_debug == 11) { Melder_warning (i, " \"", item -> d_widget -> name, "\""); } } else { XmToggleButtonSetState (item -> d_widget, FALSE, FALSE); } } }
void Melder_system (const wchar_t *command) { #if defined (macintosh) || defined (UNIX) if (system (Melder_peekWcsToUtf8 (command)) != 0) Melder_throw ("System command failed."); #elif defined (_WIN32) STARTUPINFO siStartInfo; PROCESS_INFORMATION piProcInfo; wchar_t *comspec = Melder_getenv (L"COMSPEC"); // e.g. "C:\WINDOWS\COMMAND.COM" or "C:\WINNT\windows32\cmd.exe" if (comspec == NULL) { comspec = Melder_getenv (L"ComSpec"); } MelderString buffer = { 0 }; if (comspec != NULL) { MelderString_copy (& buffer, comspec); } else { OSVERSIONINFOEX osVersionInfo; memset (& osVersionInfo, 0, sizeof (OSVERSIONINFOEX)); osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) { osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) Melder_throw ("System command cannot find system version."); } switch (osVersionInfo. dwPlatformId) { case VER_PLATFORM_WIN32_NT: { MelderString_copy (& buffer, L"cmd.exe"); } break; case VER_PLATFORM_WIN32_WINDOWS: { MelderString_copy (& buffer, L"command.com"); } break; default: { MelderString_copy (& buffer, L"command.com"); } } } MelderString_append (& buffer, L" /c ", command); memset (& siStartInfo, 0, sizeof (siStartInfo)); siStartInfo. cb = sizeof (siStartInfo); if (! CreateProcess (NULL, buffer.string, NULL, NULL, TRUE, 0, NULL, NULL, & siStartInfo, & piProcInfo)) Melder_throw ("Cannot create subprocess."); WaitForSingleObject (piProcInfo. hProcess, -1); CloseHandle (piProcInfo. hProcess); CloseHandle (piProcInfo. hThread); #endif }
/* BSD systems provide ftruncate, several others supply chsize, and a few may provide a (possibly undocumented) fcntl option F_FREESP. Under MS-DOS, you can sometimes use write(fd, "", 0). However, there is no portable solution, nor a way to delete blocks at the beginning. */ static void MelderFile_truncate (MelderFile me, long size) { #if defined(_WIN32) HANDLE hFile; DWORD fdwAccess = GENERIC_READ | GENERIC_WRITE, fPos; DWORD fdwShareMode = 0; /* File cannot be shared */ LPSECURITY_ATTRIBUTES lpsa = NULL; DWORD fdwCreate = OPEN_EXISTING; LARGE_INTEGER fileSize; MelderFile_close (me); hFile = CreateFileW (my path, fdwAccess, fdwShareMode, lpsa, fdwCreate, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { Melder_throw ("Can't open file ", MelderFile_messageName (me), "."); } // Set current file pointer to position 'size' fileSize.LowPart = size; fileSize.HighPart = 0; /* Limit the file size to 2^32 - 2 bytes */ fPos = SetFilePointer (hFile, fileSize.LowPart, &fileSize.HighPart, FILE_BEGIN); if (fPos == 0xFFFFFFFF) { Melder_throw ("Can't set the position at size ", size, "for file ", MelderFile_messageName (me), "."); } // Limit the file size as the current position of the file pointer. SetEndOfFile (hFile); CloseHandle (hFile); #elif defined(linux) || defined(macintosh) MelderFile_close (me); if (truncate (Melder_peekWcsToUtf8 (my path), size) == -1) Melder_throw ("Truncating failed for file ", MelderFile_messageName (me), " (", Melder_peekUtf8ToWcs (strerror (errno)), ")."); #else Melder_throw ("Don't know what to do."); #endif }
return true; } return false; } #else #endif #endif GuiObject GuiButton_create (GuiObject parent, int left, int right, int top, int bottom, const wchar_t *buttonText, void (*activateCallback) (void *boss, GuiButtonEvent event), void *activateBoss, unsigned long flags) { GuiButton me = Melder_calloc_f (struct structGuiButton, 1); my activateCallback = activateCallback; my activateBoss = activateBoss; #if gtk my widget = gtk_button_new_with_label (Melder_peekWcsToUtf8 (buttonText)); _GuiObject_setUserData (my widget, me); // _GuiObject_position (my widget, left, right, top, bottom); // TODO: use gtk_box_pack_start(GTK_BOX(parent), my widget, FALSE, FALSE, ?) if (parent) gtk_container_add (GTK_CONTAINER (parent), GTK_WIDGET (my widget)); if (flags & GuiButton_DEFAULT || flags & GuiButton_ATTRACTIVE) { GTK_WIDGET_SET_FLAGS (my widget, GTK_CAN_DEFAULT); GtkWidget *shell = gtk_widget_get_toplevel (GTK_WIDGET (my widget)); gtk_window_set_default (GTK_WINDOW (shell), GTK_WIDGET (my widget)); } else if (1) { gtk_button_set_focus_on_click (GTK_BUTTON (my widget), false); GTK_WIDGET_UNSET_FLAGS (my widget, GTK_CAN_DEFAULT); } g_signal_connect (G_OBJECT (my widget), "destroy",
TextGrid TextGrid_readFromTIMITLabelFile (MelderFile file, int phnFile) { try { double dt = 1.0 / 16000; /* 1 / (TIMIT samplingFrequency) */ double xmax = dt; autofile f = Melder_fopen (file, "r"); // Ending time will only be known after all labels have been read. // We start with a sufficiently long duration (one hour) and correct this later. autoTextGrid me = TextGrid_create (0, 3600, L"wrd", 0); IntervalTier timit = (IntervalTier) my tiers -> item[1]; long linesRead = 0; char line[200], label[200]; while (fgets (line, 199, f)) { long it1, it2; linesRead++; if (sscanf (line, "%ld%ld%s", &it1, &it2, label) != 3) { Melder_throw ("Incorrect number of items."); } if (it1 < 0 || it2 <= it1) { Melder_throw (L"Incorrect time at line ", linesRead); } xmax = it2 * dt; double xmin = it1 * dt; long ni = timit -> intervals -> size - 1; if (ni < 1) { ni = 1; // Some files do not start with a first line "0 <number2> h#". // Instead they start with "<number1> <number2> h#", where number1 > 0. // We override number1 with 0. */ if (xmin > 0 && phnFile) { xmin = 0; } } TextInterval interval = (TextInterval) timit -> intervals -> item[ni]; if (xmin < interval -> xmax && linesRead > 1) { xmin = interval -> xmax; Melder_warning (L"File \"", MelderFile_messageName (file), L"\": Start time set to previous end " "time for label at line ", Melder_integer (linesRead), L"."); } // standard: new TextInterval const char *labelstring = (strncmp (label, "h#", 2) ? label : TIMIT_DELIMITER); IntervalTier_add (timit, xmin, xmax, Melder_peekUtf8ToWcs (labelstring)); } // Now correct the end times, based on last read interval. // (end time was set to large value!) if (timit -> intervals -> size < 2) { Melder_throw ("Empty TextGrid"); } Collection_removeItem (timit -> intervals, timit -> intervals -> size); TextInterval interval = (TextInterval) timit -> intervals -> item[timit -> intervals -> size]; timit -> xmax = interval -> xmax; my xmax = xmax; if (phnFile) { // Create tier 2 with IPA symbols autoIntervalTier ipa = Data_copy (timit); Thing_setName (ipa.peek(), L"ipa"); // First change the data in ipa for (long i = 1; i <= ipa -> intervals -> size; i++) { interval = (TextInterval) timit -> intervals -> item[i]; TextInterval_setText ( (TextInterval) ipa -> intervals -> item[i], Melder_peekUtf8ToWcs (timitLabelToIpaLabel (Melder_peekWcsToUtf8 (interval -> text)))); } Collection_addItem (my tiers, ipa.transfer()); // Then: add to collection Thing_setName (timit, L"phn"); // rename wrd } f.close (file); return me.transfer(); } catch (MelderError) { Melder_throw ("TextGrid not read from file ", file, "."); } }
GuiObject GuiMenu_addItem (GuiObject menu, const wchar_t *title, long flags, void (*commandCallback) (GuiObject, XtPointer, XtPointer), const void *closure) { Boolean toggle = flags & (GuiMenu_CHECKBUTTON | GuiMenu_RADIO_FIRST | GuiMenu_RADIO_NEXT | GuiMenu_TOGGLE_ON) ? True : False; GuiObject button; int accelerator = flags & 127; Melder_assert (title != NULL); if (toggle) { if (flags & (GuiMenu_RADIO_FIRST)) group = NULL; if (flags & (GuiMenu_RADIO_FIRST | GuiMenu_RADIO_NEXT)) { button = gtk_radio_menu_item_new_with_label (group, Melder_peekWcsToUtf8 (title)); group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button)); //Melder_casual ("Created a radio menu item with title %ls, group %ld", title, group); } else { button = gtk_check_menu_item_new_with_label (Melder_peekWcsToUtf8 (title)); } } else { button = gtk_menu_item_new_with_label (Melder_peekWcsToUtf8 (title)); } gtk_menu_shell_append (GTK_MENU_SHELL (menu), button); Melder_assert (button != NULL); if (flags & GuiMenu_INSENSITIVE) GuiObject_setSensitive (button, false); if (flags & GuiMenu_TOGGLE_ON) gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button), TRUE); if (accelerator) { /* * For printable characters, the Command key is assumed. */ if (accelerator >= 32) flags |= GuiMenu_COMMAND; static const guint acceleratorKeys [] = { 0, GDK_Left, GDK_Right, GDK_Up, GDK_Down, GDK_Pause, GDK_Delete, GDK_Insert, GDK_BackSpace, GDK_Tab, GDK_Return, GDK_Home, GDK_End, GDK_Return, GDK_Page_Up, GDK_Page_Down, GDK_Escape, GDK_F1, GDK_F2, GDK_F3, GDK_F4, GDK_F5, GDK_F6, GDK_F7, GDK_F8, GDK_F9, GDK_F10, GDK_F11, GDK_F12, 0, 0, 0 }; int modifiers = 0; if (flags & GuiMenu_COMMAND) modifiers |= GDK_CONTROL_MASK; if (flags & GuiMenu_SHIFT) modifiers |= GDK_SHIFT_MASK; if (flags & GuiMenu_OPTION) modifiers |= GDK_MOD1_MASK; guint key; if (accelerator < 32) { key = acceleratorKeys [accelerator]; } else { // gdk key symbols in the ASCII range are equal to ASCII key = accelerator; } GtkAccelGroup *ag = gtk_menu_get_accel_group (GTK_MENU (menu)); if (key != 0) gtk_widget_add_accelerator (button, toggle ? "toggled" : "activate", ag, key, (GdkModifierType)modifiers, GTK_ACCEL_VISIBLE); } #if mac if (flags & GuiMenu_ATTRACTIVE) { //Melder_casual ("attractive!"); SetItemStyle (button -> nat.entry.handle, button -> nat.entry.item, bold); } #endif if (commandCallback != NULL) { gulong handlerId = g_signal_connect (G_OBJECT (button), toggle ? "toggled" : "activate", G_CALLBACK (commandCallback), (gpointer) closure); g_object_set_data (G_OBJECT (button), "handlerId", (gpointer) handlerId); g_object_set_data (G_OBJECT (button), "commandCallback", (gpointer) commandCallback); g_object_set_data (G_OBJECT (button), "commandClosure", (gpointer) closure); } else { gtk_widget_set_sensitive (button, FALSE); } gtk_widget_show (button); return button; }
int Printer_print (void (*draw) (void *boss, Graphics g), void *boss) { #if defined (UNIX) structMelderFile tempFile = { 0 }; char tempPath_utf8 [] = "/tmp/picXXXXXX"; close (mkstemp (tempPath_utf8)); Melder_pathToFile (Melder_peekUtf8ToWcs (tempPath_utf8), & tempFile); thePrinter. graphics = Graphics_create_postscriptjob (& tempFile, thePrinter. resolution, thePrinter. spots, thePrinter. paperSize, thePrinter. orientation, thePrinter. magnification); if (! thePrinter. graphics) return Melder_error1 (L"Cannot create temporary PostScript file for printing."); draw (boss, thePrinter. graphics); forget (thePrinter. graphics); char command [500]; sprintf (command, Melder_peekWcsToUtf8 (Site_getPrintCommand ()), tempPath_utf8); system (command); MelderFile_delete (& tempFile); #elif defined (_WIN32) int postScriptCode = POSTSCRIPT_PASSTHROUGH; DOCINFO docInfo; DEVMODE *devMode; initPrinter (); if (! theWinPrint. hDevMode) { memset (& theWinPrint, 0, sizeof (PRINTDLG)); theWinPrint. lStructSize = sizeof (PRINTDLG); theWinPrint. Flags = PD_RETURNDEFAULT; if (! PrintDlg (& theWinPrint)) return Melder_error1 (L"Cannot initialize printer."); } if (Melder_backgrounding) { theWinPrint. Flags = PD_RETURNDEFAULT | PD_RETURNDC; if (! PrintDlg (& theWinPrint) || theWinPrint. hDC == NULL) { return Melder_error1 (L"Cannot print from a script on this computer."); } } else { theWinPrint. Flags &= ~ PD_RETURNDEFAULT; theWinPrint. Flags |= PD_RETURNDC; if (! PrintDlg (& theWinPrint)) return 1; } theWinDC = theWinPrint. hDC; thePrinter. postScript = thePrinter. allowDirectPostScript && Escape (theWinDC, QUERYESCSUPPORT, sizeof (int), (LPSTR) & postScriptCode, NULL); /* * The HP colour inkjet printer returns in dmFields: * 0, 1, 8, 9, 10, 11, 12, 13, 14, 15, 23, 24, 25, 26 = DM_ORIENTATION | * DM_PAPERSIZE | DM_COPIES | DM_DEFAULTSOURCE | DM_PRINTQUALITY | * DM_COLOR | DM_DUPLEX | DM_YRESOLUTION | DM_TTOPTION | DM_COLLATE | * DM_ICMMETHOD | DM_ICMINTENT | DM_MEDIATYPE | DM_DITHERTYPE */ devMode = * (DEVMODE **) theWinPrint. hDevMode; thePrinter. resolution = devMode -> dmFields & DM_YRESOLUTION ? devMode -> dmYResolution : devMode -> dmFields & DM_PRINTQUALITY ? ( devMode -> dmPrintQuality > 0 ? devMode -> dmPrintQuality : 300 ) : 300; if (devMode -> dmFields & DM_PAPERWIDTH) { thePrinter. paperWidth = devMode -> dmPaperWidth * thePrinter. resolution / 254; thePrinter. paperHeight = devMode -> dmPaperLength * thePrinter. resolution / 254; } else if (devMode -> dmFields & DM_PAPERSIZE) { static struct { float width, height; } sizes [] = { { 0, 0 }, { 8.5, 11 }, { 8.5, 11 }, { 11, 17 }, { 17, 11 }, { 8.5, 14 }, { 5.5, 8.5 }, { 7.25, 10.5 }, { 297/25.4, 420/25.4 }, { 210/25.4, 297/25.4 }, { 210/25.4, 297/25.4 }, { 148.5/25.4, 210/25.4 }, { 250/25.4, 354/25.4 }, { 182/25.4, 257/25.4 }, { 8.5, 13 }, { 215/25.4, 275/25.4 }, { 10, 14 }, { 11, 17 }, { 8.5, 11 }, { 3.875, 8.875 }, { 4.125, 9.5 }, { 4.5, 10.375 } }; int paperSize = devMode -> dmPaperSize; if (paperSize <= 0 || paperSize > 21) paperSize = 1; thePrinter. paperWidth = sizes [paperSize]. width * thePrinter. resolution; thePrinter. paperHeight = sizes [paperSize]. height * thePrinter. resolution; if (devMode -> dmOrientation == DMORIENT_LANDSCAPE) { long dummy = thePrinter. paperWidth; thePrinter. paperWidth = thePrinter. paperHeight; thePrinter. paperHeight = dummy; } } else { thePrinter. paperWidth = 1000; thePrinter. paperHeight = 1000; } EnableWindow ((HWND) XtWindow (theCurrentPraatApplication -> topShell), FALSE); SetAbortProc (theWinDC, AbortFunc); memset (& docInfo, 0, sizeof (DOCINFO)); docInfo. cbSize = sizeof (DOCINFO); docInfo. lpszDocName = L"Praatjes"; docInfo. lpszOutput = NULL; if (thePrinter. postScript) { StartDoc (theWinDC, & docInfo); StartPage (theWinDC); initPostScriptPage (); thePrinter. graphics = Graphics_create_postscriptprinter (); if (! thePrinter. graphics) return Melder_error1 (L"Cannot open printer."); draw (boss, thePrinter. graphics); forget (thePrinter. graphics); exitPostScriptPage (); EndPage (theWinDC); EndDoc (theWinDC); } else { StartDoc (theWinDC, & docInfo); StartPage (theWinDC); thePrinter. graphics = Graphics_create_screenPrinter (NULL, (unsigned long) theWinDC); if (! thePrinter. graphics) return Melder_error1 (L"Cannot open printer."); draw (boss, thePrinter. graphics); forget (thePrinter. graphics); if (EndPage (theWinDC) < 0) { Melder_error1 (L"Cannot print page."); } else { EndDoc (theWinDC); } } EnableWindow ((HWND) XtWindow (theCurrentPraatApplication -> topShell), TRUE); DeleteDC (theWinDC), theWinDC = NULL; #elif defined (macintosh) Boolean result; initPrinter (); if (Melder_backgrounding) { PMSessionValidatePageFormat (theMacPrintSession, theMacPageFormat, & result); PMSessionValidatePrintSettings (theMacPrintSession, theMacPrintSettings, & result); } else { Boolean accepted; PMSessionPrintDialog (theMacPrintSession, theMacPrintSettings, theMacPageFormat, & accepted); if (! accepted) return 1; /* Normal cancelled return. */ } PMSessionValidatePageFormat (theMacPrintSession, theMacPageFormat, & result); PMSessionValidatePrintSettings (theMacPrintSession, theMacPrintSettings, & result); PMResolution res; PMGetResolution (theMacPageFormat, & res); thePrinter. resolution = res. hRes; PMGetAdjustedPaperRect (theMacPageFormat, & paperSize); thePrinter. paperWidth = paperSize. right - paperSize. left; thePrinter. paperHeight = paperSize. bottom - paperSize. top; Boolean isPostScriptDriver = FALSE; //PMSessionIsDocumentFormatSupported (theMacPrintSession, // kPMDocumentFormatPICTPS, & isPostScriptDriver); CFArrayRef supportedFormats; PMSessionGetDocumentFormatGeneration (theMacPrintSession, & supportedFormats); CFIndex numberOfSupportedFormats = CFArrayGetCount (supportedFormats); if (Melder_debug == 21) { MelderInfo_open (); MelderInfo_writeLine1 (L"Supported document formats:"); } for (CFIndex i = 0; i < numberOfSupportedFormats; i ++) { CFStringRef supportedFormat = CFArrayGetValueAtIndex (supportedFormats, i); if (CFStringCompare (supportedFormat, kPMDocumentFormatPICTPS, 0) == 0) { isPostScriptDriver = TRUE; } if (Melder_debug == 21) { MelderInfo_writeLine3 (Melder_integer (i), L": ", Melder_peekUtf8ToWcs (CFStringGetCStringPtr (supportedFormat, kCFStringEncodingUTF8))); } } if (Melder_debug == 21) { MelderInfo_close (); } CFRelease (supportedFormats); isPostScriptDriver = FALSE; // OVERRIDE, because from 10.4 on we have something better: we'll be sending PDF thePrinter. postScript = thePrinter. allowDirectPostScript && isPostScriptDriver; if (thePrinter. postScript) { CFStringRef strings [1]; strings [0] = kPMGraphicsContextQuickdraw; CFArrayRef array = CFArrayCreate (kCFAllocatorDefault, (const void **) strings, 1, & kCFTypeArrayCallBacks); OSStatus err = PMSessionSetDocumentFormatGeneration (theMacPrintSession, kPMDocumentFormatPICTPS, array, NULL); CFRelease (array); if (err != 0) { return Melder_error2 (L"PMSessionSetDocumentFormatGeneration: error ", Melder_integer (err)); } } PMOrientation orientation; PMGetOrientation (theMacPageFormat, & orientation); thePrinter. orientation = orientation == kPMLandscape || orientation == kPMReverseLandscape ? kGraphicsPostscript_orientation_LANDSCAPE : kGraphicsPostscript_orientation_PORTRAIT; PMSessionBeginDocument (theMacPrintSession, theMacPrintSettings, theMacPageFormat); PMSessionBeginPage (theMacPrintSession, theMacPageFormat, NULL); PMSessionGetGraphicsContext (theMacPrintSession, kPMGraphicsContextQuickdraw, (void **) & theMacPort); /* * On PostScript, the point (0, 0) is the bottom left corner of the paper, which is fine. * On the screen, however, the point (0, 0) is the top left corner of the writable page. * Since we want paper-related margins, not writable-page-related margins, * we require that this point gets the coordinates (250, 258) or so, * so that the top left corner of the paper gets coordinates (0, 0). * The "left" and "top" attributes of rPaper are negative values (e.g. -250 and -258), * so multiply them by -1. * * Under Carbon, the port has to be set inside the page. */ SetPort (theMacPort); if (! thePrinter. postScript) SetOrigin (- paperSize. left, - paperSize. top); if (thePrinter. postScript) { if (! openPostScript ()) error1 (L"Cannot print PostScript.") thePrinter. graphics = Graphics_create_postscriptprinter (); if (! thePrinter. graphics) goto end; draw (boss, thePrinter. graphics); forget (thePrinter. graphics); closePostScript (); } else { thePrinter. graphics = Graphics_create_screenPrinter (NULL, (unsigned long) theMacPort); draw (boss, thePrinter. graphics); forget (thePrinter. graphics); } end: if (theMacPort) { PMSessionEndPage (theMacPrintSession); PMSessionEndDocument (theMacPrintSession); theMacPort = NULL; } #endif iferror return 0; return 1; }