1#include "Mime.h" 2#include "TypeConstants.h" 3#include "Application.h" 4#include "InterfaceDefs.h" 5#include "TranslationUtils.h" 6#include "Button.h" 7#include "Errors.h" 8#include "Window.h" 9#include "Alert.h" 10#include "TextControl.h" 11#include "FindDirectory.h" 12#include "Directory.h" 13#include "Roster.h" 14#include "Bitmap.h" 15#include "OS.h" 16#include "PrintJob.h" 17 18// POSIX includes 19#include "errno.h" 20#include "malloc.h" 21#include "signal.h" 22 23#include "InstallPrinter.h" 24 25#define PRT_SERVER_SIGNATURE "application/x-vnd.Be-PSRV" 26 27#define PRT_ATTR_MIMETYPE "application/x-vnd.Be.printer\0" 28#define PRT_ATTR_STATE "free\0" 29#define PRT_ATTR_TRANSPORT "beserved\0" 30#define PRT_ATTR_TRANSPORTADDR "local\0" 31#define PRT_ATTR_CONNECTION "local\0" 32#define PRT_ATTR_COMMENTS "\0" 33 34char *printerTypes[] = { "HP PCL3 LaserJet Compatible\0" }; 35 36 37// ----- InstallPrinterView ----------------------------------------------------- 38 39InstallPrinterView::InstallPrinterView(BRect rect, char *host, char *printer) 40 : BView(rect, "InstallPrinterView", B_FOLLOW_ALL, B_WILL_DRAW) 41{ 42 strcpy(this->host, host); 43 strcpy(this->printer, printer); 44 45 rgb_color gray = ui_color(B_PANEL_BACKGROUND_COLOR); 46 SetViewColor(gray); 47 48 BRect bmpRect(0.0, 0.0, 31.0, 31.0); 49 icon = new BBitmap(bmpRect, B_CMAP8); 50 BMimeType mime("application/x-vnd.Be.printer"); 51 mime.GetIcon(icon, B_LARGE_ICON); 52 53 BRect r(55, 50, 250, 65); 54 chkDefault = new BCheckBox(r, "Default", "Make this my default printer", NULL); 55 chkDefault->SetValue(B_CONTROL_ON); 56 AddChild(chkDefault); 57 58 r.top = 70; 59 r.bottom = r.top + 20; 60 chkTestPage = new BCheckBox(r, "TestPage", "Print a test page", NULL); 61 chkTestPage->SetValue(B_CONTROL_OFF); 62 chkTestPage->SetEnabled(false); 63 AddChild(chkTestPage); 64 65 r.Set(140, 105, 260, 125); 66 BButton *okBtn = new BButton(r, "OkayBtn", "Configure Printer", new BMessage(MSG_INSTALL_OK), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM); 67 okBtn->MakeDefault(true); 68 AddChild(okBtn); 69 70 r.Set(270, 105, 340, 125); 71 AddChild(new BButton(r, "CancelBtn", "Cancel", new BMessage(MSG_INSTALL_CANCEL), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM)); 72} 73 74InstallPrinterView::~InstallPrinterView() 75{ 76} 77 78void InstallPrinterView::Draw(BRect rect) 79{ 80 BRect r = Bounds(); 81 BRect iconRect(13.0, 5.0, 45.0, 37.0); 82 rgb_color black = { 0, 0, 0, 255 }; 83 rgb_color gray = ui_color(B_PANEL_BACKGROUND_COLOR); 84 char msg[512]; 85 86 SetViewColor(gray); 87 SetLowColor(gray); 88 FillRect(r, B_SOLID_LOW); 89 90 SetHighColor(black); 91 SetFont(be_bold_font); 92 SetFontSize(11); 93 MovePenTo(55, 15); 94 DrawString("Configure this Printer?"); 95 96 sprintf(msg, "'%s' on computer '%s?'", printer, host); 97 SetFont(be_plain_font); 98 SetFontSize(10); 99 MovePenTo(55, 28); 100 DrawString("Would you like to configure your computer to print to printer"); 101 MovePenTo(55, 40); 102 DrawString(msg); 103 104 SetDrawingMode(B_OP_ALPHA); 105 SetHighColor(0, 0, 0, 180); 106 SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); 107 DrawBitmap(icon, iconRect); 108} 109 110 111// ----- InstallPrinterPanel ---------------------------------------------------------------------- 112 113InstallPrinterPanel::InstallPrinterPanel(BRect frame, char *host, char *printer) 114 : BWindow(frame, "New Printer", B_MODAL_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL, B_NOT_ZOOMABLE | B_NOT_RESIZABLE) 115{ 116 cancelled = false; 117 118 BRect r = Bounds(); 119 installView = new InstallPrinterView(r, host, printer); 120 AddChild(installView); 121 122 Show(); 123} 124 125InstallPrinterPanel::~InstallPrinterPanel() 126{ 127} 128 129// MessageReceived() 130// 131void InstallPrinterPanel::MessageReceived(BMessage *msg) 132{ 133 switch (msg->what) 134 { 135 case MSG_INSTALL_OK: 136 cancelled = false; 137 defaultPrinter = installView->isDefault(); 138 sendTestPage = installView->printTestPage(); 139 BWindow::Quit(); 140 break; 141 142 case MSG_INSTALL_CANCEL: 143 cancelled = true; 144 BWindow::Quit(); 145 break; 146 147 default: 148 BWindow::MessageReceived(msg); 149 break; 150 } 151} 152 153// CreatePrinter() 154// 155bool InstallPrinterPanel::CreatePrinter(char *printer, char *host, int type, char *user, char *password) 156{ 157 char path[B_PATH_NAME_LENGTH], msg[B_PATH_NAME_LENGTH + 256]; 158 159 // Create the printer spooling folder. If it cannot be created, we'll have to abort. 160 find_directory(B_USER_SETTINGS_DIRECTORY, 0, false, path, sizeof(path)); 161 strcat(path, "/printers/"); 162 strcat(path, printer); 163 if (create_directory(path, S_IRWXU | S_IRWXG | S_IRWXO) != B_OK) 164 { 165 sprintf(msg, "A printer spooling folder, %s, could not be created.", path); 166 BAlert *alert = new BAlert("", msg, "OK"); 167 alert->Go(); 168 return false; 169 } 170 171 // Now set the necessary attributes for the printing system to work. This includes 172 // standard BeOS attributes, such as BEOS:TYPE and Driver Name, but also includes those 173 // specific to BeServed, such as "server," which identifies the remote host. 174 int file = open(path, O_RDONLY); 175 if (file >= 0) 176 { 177 fs_write_attr(file, "BEOS:TYPE", B_STRING_TYPE, 0, PRT_ATTR_MIMETYPE, strlen(PRT_ATTR_MIMETYPE) + 1); 178 fs_write_attr(file, "Driver Name", B_STRING_TYPE, 0, printerTypes[type], strlen(printerTypes[type]) + 1); 179 fs_write_attr(file, "Printer Name", B_STRING_TYPE, 0, printer, strlen(printer) + 1); 180 fs_write_attr(file, "state", B_STRING_TYPE, 0, PRT_ATTR_STATE, strlen(PRT_ATTR_STATE) + 1); 181 fs_write_attr(file, "transport", B_STRING_TYPE, 0, PRT_ATTR_TRANSPORT, strlen(PRT_ATTR_TRANSPORT) + 1); 182 fs_write_attr(file, "transport_address", B_STRING_TYPE, 0, PRT_ATTR_TRANSPORTADDR, strlen(PRT_ATTR_TRANSPORTADDR) + 1); 183 fs_write_attr(file, "connection", B_STRING_TYPE, 0, PRT_ATTR_CONNECTION, strlen(PRT_ATTR_CONNECTION) + 1); 184 fs_write_attr(file, "Comments", B_STRING_TYPE, 0, PRT_ATTR_COMMENTS, strlen(PRT_ATTR_COMMENTS) + 1); 185 fs_write_attr(file, "server", B_STRING_TYPE, 0, host, strlen(host) + 1); 186 fs_write_attr(file, "user", B_STRING_TYPE, 0, user, strlen(user) + 1); 187 fs_write_attr(file, "password", B_STRING_TYPE, 0, password, BT_AUTH_TOKEN_LENGTH + 1); 188 close(file); 189 } 190 191// if (!NotifyPrintServer(printer, type)) 192 RestartPrintServer(); 193 194 return true; 195} 196 197void InstallPrinterPanel::RestartPrintServer() 198{ 199 app_info appInfo; 200 201 if (be_roster->GetAppInfo(PRT_SERVER_SIGNATURE, &appInfo) == B_OK) 202 { 203 int retries = 0; 204 kill(appInfo.thread, SIGTERM); 205 while (be_roster->IsRunning(PRT_SERVER_SIGNATURE) && retries++ < 5) 206 sleep(1); 207 } 208 209 be_roster->Launch(PRT_SERVER_SIGNATURE); 210} 211 212void InstallPrinterPanel::SetDefaultPrinter(char *printer) 213{ 214 FILE *fp; 215 char path[B_PATH_NAME_LENGTH]; 216 int i; 217 218 // Create the printer spooling folder. If it cannot be created, we'll have to abort. 219 find_directory(B_USER_SETTINGS_DIRECTORY, 0, false, path, sizeof(path)); 220 strcat(path, "/printer_data"); 221 222 fp = fopen(path, "wb"); 223 if (fp) 224 { 225 fputs(printer, fp); 226 for (i = strlen(printer); i < 256; i++) 227 fputc('\0', fp); 228 229 fclose(fp); 230 } 231} 232 233bool InstallPrinterPanel::NotifyPrintServer(char *printer, int type) 234{ 235 BMessage msg('selp'); 236 BMessenger msgr; 237 238 if (!GetPrintServerMessenger(msgr)) 239 return false; 240 241 msg.AddString("driver", printerTypes[type]); 242 msg.AddString("transport", PRT_ATTR_TRANSPORT); 243 msg.AddString("transport path", PRT_ATTR_TRANSPORTADDR); 244 msg.AddString("printer name", printer); 245 msg.AddString("connection", PRT_ATTR_CONNECTION); 246 msgr.SendMessage(&msg); 247 return true; 248} 249 250bool InstallPrinterPanel::GetPrintServerMessenger(BMessenger &msgr) 251{ 252 if (!be_roster->IsRunning(PRT_SERVER_SIGNATURE)) 253 be_roster->Launch(PRT_SERVER_SIGNATURE); 254 255 msgr = BMessenger(PRT_SERVER_SIGNATURE); 256 return msgr.IsValid(); 257} 258 259 260void InstallPrinterPanel::TestPrinter(char *printer) 261{ 262 char *jobName = new char [strlen(printer) + 20]; 263 if (!jobName) 264 return; 265 266 sprintf(jobName, "%s Test Page", printer); 267 BPrintJob job(jobName); 268 269 if (job.ConfigPage() == B_OK) 270 if (job.ConfigJob() == B_OK) 271 { 272 BRect printableRect = job.PrintableRect(); 273 BPoint startPoint(printableRect.left, printableRect.top); 274 TestPrintView *testView = new TestPrintView(printableRect); 275 276 job.BeginJob(); 277 job.DrawView(testView, printableRect, startPoint); 278 job.SpoolPage(); 279 job.CommitJob(); 280 281 delete testView; 282 } 283 284 delete jobName; 285} 286 287// ----- TestPrintView ------------------------------------------------------------------------ 288 289TestPrintView::TestPrintView(BRect rect) 290 : BView(rect, "TestPrintView", B_FOLLOW_ALL, B_WILL_DRAW) 291{ 292 BMessage archive; 293 size_t size; 294 char *bits; 295 296 rgb_color white = { 255, 255, 255, 255 }; 297 SetViewColor(white); 298 299// bits = (char *) be_app->AppResources()->LoadResource(type_code('BBMP'), BMP_TESTPAGE_LOGO, &size); 300// if (bits) 301// if (archive.Unflatten(bits) == B_OK) 302// beServedIcon = new BBitmap(&archive); 303} 304 305TestPrintView::~TestPrintView() 306{ 307} 308 309void TestPrintView::Draw(BRect rect) 310{ 311 BRect iconRect(13.0, 5.0, 45.0, 37.0); 312 rgb_color black = { 0, 0, 0, 255 }; 313 rgb_color white = { 255, 255, 255, 255 }; 314 315 SetViewColor(white); 316 SetLowColor(white); 317 318 SetHighColor(black); 319 SetFont(be_bold_font); 320 SetFontSize(11); 321 MovePenTo(55, 15); 322 DrawString(""); 323 324 SetFont(be_plain_font); 325 SetFontSize(10); 326 MovePenTo(55, 28); 327 DrawString("This test page has been sent to your printer by request. By reading this information, you are confirming"); 328 MovePenTo(55, 40); 329 DrawString("that this printer is communicating correctly with the computer from which this test was sent."); 330 331 SetDrawingMode(B_OP_ALPHA); 332 SetHighColor(0, 0, 0, 180); 333 SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); 334 DrawBitmap(beServedIcon, iconRect); 335} 336