| | 4924 | } |
|---|
| | 4925 | |
|---|
| | 4926 | DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name, |
|---|
| | 4927 | 0, 0, 0, doc: /* Return the name of Windows default printer device. */) |
|---|
| | 4928 | () |
|---|
| | 4929 | { |
|---|
| | 4930 | static char pname_buf[256]; |
|---|
| | 4931 | int err; |
|---|
| | 4932 | HANDLE hPrn; |
|---|
| | 4933 | PRINTER_INFO_2 *ppi2 = NULL; |
|---|
| | 4934 | DWORD dwNeeded = 0, dwReturned = 0; |
|---|
| | 4935 | |
|---|
| | 4936 | /* Retrieve the default string from Win.ini (the registry). |
|---|
| | 4937 | * String will be in form "printername,drivername,portname". |
|---|
| | 4938 | * This is the most portable way to get the default printer. */ |
|---|
| | 4939 | if (GetProfileString ("windows", "device", ",,", pname_buf, sizeof (pname_buf)) <= 0) |
|---|
| | 4940 | return Qnil; |
|---|
| | 4941 | /* printername precedes first "," character */ |
|---|
| | 4942 | strtok (pname_buf, ","); |
|---|
| | 4943 | /* We want to know more than the printer name */ |
|---|
| | 4944 | if (!OpenPrinter (pname_buf, &hPrn, NULL)) |
|---|
| | 4945 | return Qnil; |
|---|
| | 4946 | GetPrinter (hPrn, 2, NULL, 0, &dwNeeded); |
|---|
| | 4947 | if (dwNeeded == 0) |
|---|
| | 4948 | { |
|---|
| | 4949 | ClosePrinter (hPrn); |
|---|
| | 4950 | return Qnil; |
|---|
| | 4951 | } |
|---|
| | 4952 | /* Allocate memory for the PRINTER_INFO_2 struct */ |
|---|
| | 4953 | ppi2 = (PRINTER_INFO_2 *) xmalloc (dwNeeded); |
|---|
| | 4954 | if (!ppi2) |
|---|
| | 4955 | { |
|---|
| | 4956 | ClosePrinter (hPrn); |
|---|
| | 4957 | return Qnil; |
|---|
| | 4958 | } |
|---|
| | 4959 | /* Call GetPrinter() again with big enouth memory block */ |
|---|
| | 4960 | err = GetPrinter (hPrn, 2, (LPBYTE)ppi2, dwNeeded, &dwReturned); |
|---|
| | 4961 | ClosePrinter (hPrn); |
|---|
| | 4962 | if (!err) |
|---|
| | 4963 | { |
|---|
| | 4964 | xfree(ppi2); |
|---|
| | 4965 | return Qnil; |
|---|
| | 4966 | } |
|---|
| | 4967 | |
|---|
| | 4968 | if (ppi2) |
|---|
| | 4969 | { |
|---|
| | 4970 | if (ppi2->Attributes & PRINTER_ATTRIBUTE_SHARED && ppi2->pServerName) |
|---|
| | 4971 | { |
|---|
| | 4972 | /* a remote printer */ |
|---|
| | 4973 | if (*ppi2->pServerName == '\\') |
|---|
| | 4974 | _snprintf(pname_buf, sizeof (pname_buf), "%s\\%s", ppi2->pServerName, |
|---|
| | 4975 | ppi2->pShareName); |
|---|
| | 4976 | else |
|---|
| | 4977 | _snprintf(pname_buf, sizeof (pname_buf), "\\\\%s\\%s", ppi2->pServerName, |
|---|
| | 4978 | ppi2->pShareName); |
|---|
| | 4979 | pname_buf[sizeof (pname_buf) - 1] = '\0'; |
|---|
| | 4980 | } |
|---|
| | 4981 | else |
|---|
| | 4982 | { |
|---|
| | 4983 | /* a local printer */ |
|---|
| | 4984 | strncpy(pname_buf, ppi2->pPortName, sizeof (pname_buf)); |
|---|
| | 4985 | pname_buf[sizeof (pname_buf) - 1] = '\0'; |
|---|
| | 4986 | /* `pPortName' can include several ports, delimited by ','. |
|---|
| | 4987 | * we only use the first one. */ |
|---|
| | 4988 | strtok(pname_buf, ","); |
|---|
| | 4989 | } |
|---|
| | 4990 | xfree(ppi2); |
|---|
| | 4991 | } |
|---|
| | 4992 | |
|---|
| | 4993 | return build_string (pname_buf); |
|---|