-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathprinterinfo.cpp
More file actions
118 lines (104 loc) · 3.68 KB
/
printerinfo.cpp
File metadata and controls
118 lines (104 loc) · 3.68 KB
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include "FileStreambuf.hpp"
#include "libcapt/Protocol/ExtendedStatus.hpp"
#include "libcapt/Protocol/PageParams.hpp"
#include "libcapt/Protocol/Protocol.hpp"
#include <cassert>
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstdint>
#include <span>
using namespace Capt;
static void printPrinterInfo(PrinterInfo info) {
std::puts("Printer Info:");
std::printf(" Type = %u\n", info.Type);
std::printf(" Version = %u.%02u\n", info.VersionMajor, info.VersionMinor);
std::printf(" BlockSize = %u\n", info.BlockSize);
std::printf(" Buffers = %u\n", info.Buffers);
std::printf(" RAM Total = %.02f MB\n", (static_cast<double>(info.BlockSize * info.Buffers) / 1024.0) / 1024.0);
}
static std::size_t fillBuffer(std::iostream& printerStream, std::size_t batchSize, std::size_t thresh = 0) {
std::size_t count = 0;
std::vector<uint8_t> buffer(batchSize, 0xff);
while (true) {
if (thresh != 0 && count >= thresh && batchSize != 1) {
batchSize = 1;
buffer.resize(batchSize);
}
BasicStatus bs = Protocol::PCR_GET_BASIC_STATUS(printerStream);
if ((bs & BasicStatus::IM_DATA_BUSY) != 0) {
break;
}
if ((bs & BasicStatus::CMD_BUSY) != 0) {
std::puts("\nfillBuffer error: CMD_BUSY");
break;
}
if ((bs & BasicStatus::ERROR_BIT) != 0) {
std::puts("\nfillBuffer error: ERROR_BIT");
break;
}
Protocol::IC_VIDEO_DATA(printerStream, buffer);
count += buffer.size();
std::printf("\033[2K\rFilling: %zu", count);
std::fflush(stdout);
}
std::putchar('\n');
return count;
}
int main(int argc, char* argv[]) {
if (argc != 2) {
std::printf("Usage: %s printerdev\n", argv[0]);
return 1;
}
FileStreambuf fs;
if (!fs.Open(argv[1], "r+")) {
std::puts("Failed to open printer stream");
return 1;
}
std::iostream printerStream(&fs);
PrinterInfo info = Protocol::PC_GET_PRINTER_INFO(printerStream);
printPrinterInfo(info);
if (Protocol::PC_RESERVE_UNIT(printerStream) != 0) {
std::puts("Failed to reserve unit");
return 1;
}
std::puts("Unit reserved");
Protocol::PCR_CLEAR_ERROR(printerStream);
Protocol::PCR_DISCARD_DATA(printerStream);
Protocol::PCR_GO_ONLINE(printerStream, 0);
ExtendedStatus status = Protocol::PC_GET_EXTENDED_STATUS(printerStream);
if (status.PaperAvailableBits != 0) {
std::puts("Video buffer size detection is not available: remove paper first");
return 0;
}
Protocol::IC_BEGIN_DATA(printerStream);
if ((status.Basic & BasicStatus::IM_DATA_BUSY) != 0) {
std::puts("Video buffer size detection error: IM_DATA_BUSY");
return 1;
}
PageParams dummyParams{
.PaperSize = 0x09,
.TonerDensity = 0x3f,
.Mode = 0,
.Resolution = ResolutionIdx::RES_600,
.SmoothEnable = true,
.TonerSaving = false,
.MarginLeft = 1,
.MarginTop = 1,
.ImageLineSize = 620,
.ImageLines = 7014,
.PaperWidth = 4960,
.PaperHeight = 7014,
};
Protocol::IC_BEGIN_PAGE(printerStream, dummyParams);
std::puts("Filling video buffer: pass 1...");
const std::size_t batchSize = 6144;
const std::size_t thresh = 16 * 1024;
std::size_t buffSize = fillBuffer(printerStream, batchSize);
assert(buffSize > thresh);
std::puts("Filling video buffer: pass 2...");
Protocol::PCR_DISCARD_DATA(printerStream);
buffSize = fillBuffer(printerStream, batchSize, buffSize - thresh);
std::printf("Video buffer size: %zu\n", buffSize);
return 0;
}