diff --git a/device/scanner.vcxproj b/device/scanner.vcxproj index 0d68a59..a9d9f25 100644 --- a/device/scanner.vcxproj +++ b/device/scanner.vcxproj @@ -76,6 +76,7 @@ $(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(LibraryPath) $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ + true false @@ -83,6 +84,7 @@ $(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(LibraryPath) $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ + false true @@ -90,6 +92,7 @@ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\code_device\hgdriver\3rdparty\nick;$(SolutionDir)..\..\sdk\include\opencv\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\cyusb\inc\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\libtiff\include\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\log4cplus\include\;$(SolutionDir)..\..\code_device\sdk\;$(SolutionDir)..\..\code_device\hgdriver\ImageProcess\;$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\code_device\hgdriver\hgdev\;$(SolutionDir)..\..\code_device\hgdriver\wrapper\;$(ProjectDir);$(SolutionDir)..\..\code_device\hgdriver\3rdparty\tiff\include\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\openssl\include;$(IncludePath) $(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(LibraryPath) + true false @@ -97,6 +100,7 @@ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\code_device\hgdriver\3rdparty\nick;$(SolutionDir)..\..\sdk\include\opencv\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\cyusb\inc\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\libtiff\include\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\log4cplus\include\;$(SolutionDir)..\..\code_device\sdk\;$(SolutionDir)..\..\code_device\hgdriver\ImageProcess\;$(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\code_device\hgdriver\hgdev\;$(SolutionDir)..\..\code_device\hgdriver\wrapper\;$(ProjectDir);$(SolutionDir)..\..\code_device\hgdriver\3rdparty\tiff\include\;$(SolutionDir)..\..\code_device\hgdriver\3rdparty\openssl\include;$(IncludePath) $(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(LibraryPath) + false @@ -118,8 +122,10 @@ - - + move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +copy /y "$(TargetPath)" "C:\Windows\twain_32\HuaGoTwain" @@ -147,8 +153,9 @@ - - + move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" @@ -169,8 +176,10 @@ $(ProjectDir)device.def - - + move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +copy /y "$(TargetPath)" "C:\Program Files\HuaGoScan" @@ -196,8 +205,9 @@ $(ProjectDir)device.def - - + move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" diff --git a/device/win_usb/win_usb.cpp b/device/win_usb/win_usb.cpp index d6e6952..64b5a65 100644 --- a/device/win_usb/win_usb.cpp +++ b/device/win_usb/win_usb.cpp @@ -48,9 +48,6 @@ void usb_callback::notify(libusb_context* ctx, usb_device* dev, int ev) } std::string u2utf8(const wchar_t* u) { -#if defined(OEM_NONE) || defined(OEM_LISCHENG) || defined(OEM_HANWANG) || defined(OEM_ZHONGJING) - return hg_log::u2utf8(u); -#else int len = WideCharToMultiByte(CP_UTF8, 0, u, lstrlenW(u), NULL, 0, NULL, NULL); char *ansi = new char[len + 4]; @@ -61,7 +58,6 @@ std::string u2utf8(const wchar_t* u) delete[] ansi; return utf8; -#endif } std::wstring ansi2unicode(const char* ansi, UINT cp = CP_ACP) { diff --git a/lang/lang.def b/lang/lang.def index 527189b..a53cdd5 100644 --- a/lang/lang.def +++ b/lang/lang.def @@ -10,3 +10,5 @@ EXPORTS to_default_language from_default_language lang_refresh_language + language_option_descriptor + diff --git a/lang/lang.vcxproj b/lang/lang.vcxproj index 060a9cf..5576933 100644 --- a/lang/lang.vcxproj +++ b/lang/lang.vcxproj @@ -29,7 +29,7 @@ DynamicLibrary true - v143 + v142 Unicode @@ -42,7 +42,7 @@ DynamicLibrary true - v143 + v142 Unicode @@ -74,27 +74,31 @@ $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\sdk\include;$(IncludePath) + true $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\sdk\include;$(IncludePath) + false $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\sdk\include;$(IncludePath) + true $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\sdk\include;$(IncludePath) + false Level3 true - WIN32;_DEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS + WIN32;_DEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS;VENDOR=huagao true Use pch.h @@ -106,8 +110,11 @@ lang.def - - + mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +copy /y "$(TargetPath)" "C:\Windows\twain_32\HuaGoTwain" @@ -116,7 +123,7 @@ true true true - WIN32;NDEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS + WIN32;NDEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS;OEM=huagao true Use pch.h @@ -131,15 +138,17 @@ lang.def - - + mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" Level3 true - _DEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS + _DEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS;OEM=huagao true Use pch.h @@ -151,8 +160,11 @@ lang.def - - + mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +copy /y "$(TargetPath)" "C:\Program Files\HuaGoScan" @@ -161,7 +173,7 @@ true true true - NDEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS + NDEBUG;LANG_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions);LANG_EXPORT;_CRT_SECURE_NO_WARNINGS;OEM=huagao true Use pch.h @@ -176,8 +188,10 @@ lang.def - - + mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" diff --git a/sane/DlgArea.cpp b/sane/DlgArea.cpp deleted file mode 100644 index 2b7e9fa..0000000 --- a/sane/DlgArea.cpp +++ /dev/null @@ -1,814 +0,0 @@ -// DlgIndicator.cpp: 实现文件 -// - -#include "DlgArea.h" -#include "resource.h" -#include "scanned_img.h" // for local_trans -#include "mem_dc.h" - -// CDlgIndicator 对话框 -#define MM_PER_INCH 25.4f - -int dlg_area::area_min_pixel = 50; - -dlg_area::dlg_area(HWND parent) : dlg_base(parent, IDD_AREA) - , unit_(PAPER_UNIT_MM), paper_w_(210), paper_h_(297), dpi_(200) - , x_(0), y_(0), w_(paper_w_), h_(paper_h_) - , paper_(L"A4") - , paper_w_0_(paper_w_), paper_h_0_(paper_h_), cursor_(NULL), drag_(DRAG_POS_NONE) - , in_set_func_(false) -{ - std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM_AREA)); - - create(); - - SetWindowTextW(hwnd(), title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_MM) + L" (mm)"; - SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]); - title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_INCH) + L" (inch)"; - SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]); - title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_PIXEL) + L" (px)"; - SendMessageW(get_item(IDC_UNIT), CB_ADDSTRING, 0, (LPARAM)&title[0]); - SendMessage(get_item(IDC_UNIT), CB_SETCURSEL, 0, 0); - - - if (!dlg_base::is_language_pack_default_code_page()) - { - int width_diff = 0, w = 0; - RECT r = { 0 }, rp = { 0 }; - - title = local_trans::lang_trans_between_hz936(CONST_STRING_OPT_PAPER) + L":"; - set_item_text(IDC_STATIC_PAPER, title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_UNIT) + L":"; - set_item_text(IDC_STATIC_UNIT, title.c_str()); - title = L"DPI (" + local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_PIXEL) + L"/" + local_trans::lang_trans_between_hz936(CONST_STRING_UNIT_INCH) + L"):"; - set_item_text(IDC_STATIC_DPI, title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_AREA_SET) + L":"; - set_item_text(IDC_STATIC_AREA, title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_LEFT) + L":"; - set_item_text(IDC_STATIC_LEFT, title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_TOP) + L":"; - set_item_text(IDC_STATIC_TOP, title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_WIDTH) + L":"; - set_item_text(IDC_STATIC_W, title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_HEIGHT) + L":"; - set_item_text(IDC_STATIC_H, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_RESTORE_AREA); - set_item_text(IDC_BUTTON_RESET, title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL); - set_item_text(IDCANCEL, title.c_str()); - title = local_trans::lang_trans_between_hz936(CONST_STRING_OK); - set_item_text(IDOK, title.c_str()); - - layout(); - } -} -dlg_area::~dlg_area() -{ -} - -float dlg_area::mm_2_pixel(float mm, float dpi) -{ - return inches_2_pixel(mm_2_inches(mm), dpi); -} -float dlg_area::mm_2_inches(float mm) -{ - return mm / MM_PER_INCH; -} -float dlg_area::inches_2_pixel(float inch, float dpi) -{ - return inch * dpi; -} -float dlg_area::inches_2_mm(float inch) -{ - return inch * MM_PER_INCH; -} -float dlg_area::pixel_2_mm(float px, float dpi) -{ - return inches_2_mm(pixel_2_inches(px, dpi)); -} -float dlg_area::pixel_2_inches(float px, float dpi) -{ - return px / dpi; -} - -BOOL dlg_area::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - wchar_t text[40] = { 0 }; - BOOL ret = TRUE; - - switch (msg) - { - case WM_INITDIALOG: - UpdateWindow(hwnd()); - break; - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - case WM_PAINT: - { - PAINTSTRUCT ps = { 0 }; - HDC hdc = BeginPaint(hwnd(), &ps); - { - compatible_dc dc(hdc); - on_paint(dc.get_dc()); - } - EndPaint(hwnd(), &ps); - } - break; - case WM_MOUSEMOVE: - on_mouse_move(wp, LOWORD(lp), HIWORD(lp)); - break; - case WM_LBUTTONDOWN: - on_lbutton_down(LOWORD(lp), HIWORD(lp)); - break; - case WM_LBUTTONUP: - on_lbutton_up(LOWORD(lp), HIWORD(lp)); - break; - default: - ret = FALSE; - } - return ret; -} -void dlg_area::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - if (id == IDC_UNIT) - { - if (code == CBN_SELCHANGE) - { - on_unit_changed((HWND)ctrl); - } - } - else if (id == IDCANCEL) - { - quit_modal(id); - } - else if (id == IDOK) - { - quit_modal(id); - } - else if (id == IDC_BUTTON_RESET) - { - clear_area(); - } - else if (id == IDC_EDIT_x || - id == IDC_EDIT_y || - id == IDC_EDIT_W || - id == IDC_EDIT_H) - { - if (code == EN_CHANGE && !in_set_func_) - { - wchar_t val[80] = { 0 }; - float num = .0f; - - GetWindowTextW((HWND)ctrl, val, _countof(val) - 1); - num = (float)_wtof(val); - if (id == IDC_EDIT_x) - { - if (num < .0f) - num = .0f; - if (num > paper_w_ - dlg_area::area_min_pixel) - num = paper_w_ - dlg_area::area_min_pixel; - x_ = num; - user_sel_.left = whole_.left + (LONG)(x_ / ratio_); - if (x_ + w_ > paper_w_) - w_ = paper_w_ - x_; - user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_); - refresh_paper_info(); - InvalidateRect(hwnd(), &whole_, FALSE); - } - else if (id == IDC_EDIT_y) - { - if (num < .0f) - num = .0f; - if (num > paper_h_ - dlg_area::area_min_pixel) - num = paper_h_ - dlg_area::area_min_pixel; - y_ = num; - user_sel_.top = whole_.top + (LONG)(y_ / ratio_); - if (y_ + h_ > paper_h_) - h_ = paper_h_ - y_; - user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_); - refresh_paper_info(); - InvalidateRect(hwnd(), &whole_, FALSE); - } - else if (id == IDC_EDIT_W) - { - if (num < dlg_area::area_min_pixel) - num = (float)dlg_area::area_min_pixel; - if (num > paper_w_) - num = paper_w_; - w_ = num; - user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_); - if (user_sel_.right > whole_.right) - { - OffsetRect(&user_sel_, whole_.right - user_sel_.right, 0); - if (user_sel_.left < whole_.left) - { - user_sel_.left = whole_.left; - x_ = 0; - } - } - refresh_paper_info(); - InvalidateRect(hwnd(), &whole_, FALSE); - } - else if (id == IDC_EDIT_H) - { - if (num < dlg_area::area_min_pixel) - num = (float)dlg_area::area_min_pixel; - if (num > paper_h_) - num = paper_h_; - h_ = num; - user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_); - if (user_sel_.bottom > whole_.bottom) - { - OffsetRect(&user_sel_, 0, whole_.bottom - user_sel_.bottom); - if (user_sel_.top < whole_.top) - { - user_sel_.top = whole_.top; - y_ = 0; - } - } - refresh_paper_info(); - InvalidateRect(hwnd(), &whole_, FALSE); - } - } - } -} -void dlg_area::layout(void) -{ - RECT r = { 0 }; - int w_dif = get_width_diff_as_text_length(IDC_STATIC_LEFT), - top1 = get_width_diff_as_text_length(IDC_STATIC_PAPER), - top21 = get_width_diff_as_text_length(IDC_STATIC_UNIT), - top22 = get_width_diff_as_text_length(IDC_STATIC_DPI); - -#define CHECK_CTRL_W(id) \ - if(w_dif < get_width_diff_as_text_length(id)) \ - w_dif = get_width_diff_as_text_length(id); - - CHECK_CTRL_W(IDC_STATIC_TOP); - CHECK_CTRL_W(IDC_STATIC_W); - CHECK_CTRL_W(IDC_STATIC_H); - CHECK_CTRL_W(IDC_BUTTON_RESET); - if (w_dif < top21 + top22) - w_dif = top21 + top22; - - // layout ... - if (w_dif > 0) - { - GetWindowRect(hwnd(), &r); - r.right += w_dif; - MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE); - - expand_item(IDC_STATIC_PAPER, top1, 0); - offset_item(IDC_EDIT_PAPER, top1, 0); - expand_item(IDC_EDIT_PAPER, w_dif - top1, 0); - - expand_item(IDC_STATIC_UNIT, top21, 0); - offset_item(IDC_UNIT, top21, 0); - - offset_item(IDC_STATIC_DPI, w_dif - top22, 0); - expand_item(IDC_STATIC_DPI, top22, 0); - offset_item(IDC_EDIT_DPI, top21 + top22, 0); - - expand_item(IDC_STATIC_AREA, w_dif, 0); - - expand_item(IDC_STATIC_LEFT, w_dif, 0); - offset_item(IDC_EDIT_x, w_dif, 0); - - expand_item(IDC_STATIC_TOP, w_dif, 0); - offset_item(IDC_EDIT_y, w_dif, 0); - - expand_item(IDC_STATIC_W, w_dif, 0); - offset_item(IDC_EDIT_W, w_dif, 0); - - expand_item(IDC_STATIC_H, w_dif, 0); - offset_item(IDC_EDIT_H, w_dif, 0); - - top1 = get_width_diff_as_text_length(IDC_BUTTON_RESET); - expand_item(IDC_BUTTON_RESET, top1, 0); - offset_item(IDC_BUTTON_RESET, (w_dif - top1) / 2, 0); - - offset_item(IDOK, w_dif, 0); - offset_item(IDCANCEL, w_dif, 0); - } -} - -float dlg_area::as_mm(float v) -{ - if (unit_ == PAPER_UNIT_INCH) - return dlg_area::inches_2_mm(v); - else if (unit_ == PAPER_UNIT_PIXEL) - return dlg_area::pixel_2_mm(v, dpi_); - else - return v; -} -float dlg_area::from_mm(float v) -{ - if (unit_ == PAPER_UNIT_INCH) - return dlg_area::mm_2_inches(v); - else if (unit_ == PAPER_UNIT_PIXEL) - return dlg_area::mm_2_pixel(v, dpi_); - else - return v; -} -float dlg_area::as_inches(float v) -{ - if (unit_ == PAPER_UNIT_MM) - return dlg_area::mm_2_inches(v); - else if (unit_ == PAPER_UNIT_PIXEL) - return dlg_area::pixel_2_inches(v, dpi_); - else - return v; -} -float dlg_area::as_pixels(float v) -{ - if (unit_ == PAPER_UNIT_MM) - return dlg_area::mm_2_pixel(v, dpi_); - else if (unit_ == PAPER_UNIT_INCH) - return dlg_area::inches_2_pixel(v, dpi_); - else - return v; -} -std::wstring dlg_area::format_number(float v) -{ - wchar_t str[40] = { 0 }; - - if (unit_ == PAPER_UNIT_PIXEL) - swprintf_s(str, _countof(str) - 1, L"%d", (int)(v + .5f)); - else - swprintf_s(str, _countof(str) - 1, L"%.2f", v); - - return str; -} -void dlg_area::refresh_paper_info(void) -{ - SetWindowTextW(get_item(IDC_EDIT_PAPER), (paper_ + L"(" + format_number(paper_w_) + local_trans::lang_trans_between_hz936(CONST_STRING_MULTIPLE) + format_number(paper_h_) + L")").c_str()); - SetDlgItemInt(hwnd(), IDC_EDIT_DPI, UINT(dpi_), FALSE); - - in_set_func_ = true; - SetWindowTextW(get_item(IDC_EDIT_x), format_number(x_).c_str()); - SetWindowTextW(get_item(IDC_EDIT_y), format_number(y_).c_str()); - SetWindowTextW(get_item(IDC_EDIT_W), format_number(w_).c_str()); - SetWindowTextW(get_item(IDC_EDIT_H), format_number(h_).c_str()); - in_set_func_ = false; - - InvalidateRect(hwnd(), &whole_, FALSE); -} -void dlg_area::to_unit(paper_unit unit) -{ - float(dlg_area:: * conv)(float) = NULL; - - if (unit == PAPER_UNIT_INCH) - { - conv = &dlg_area::as_inches; - paper_w_ = dlg_area::mm_2_inches(paper_w_0_); - paper_h_ = dlg_area::mm_2_inches(paper_h_0_); - } - else if (unit == PAPER_UNIT_PIXEL) - { - conv = &dlg_area::as_pixels; - paper_w_ = dlg_area::mm_2_pixel(paper_w_0_, dpi_); - paper_h_ = dlg_area::mm_2_pixel(paper_h_0_, dpi_); - } - else // if (unit == PAPER_UNIT_MM) - { - conv = &dlg_area::as_mm; - paper_w_ = paper_w_0_; - paper_h_ = paper_h_0_; - } - -#define CONV_UNIT(v) \ - v = (this->*conv)(v); - - CONV_UNIT(x_); - CONV_UNIT(y_); - CONV_UNIT(w_); - CONV_UNIT(h_); - unit_ = unit; - refresh_paper_info(); -} -void dlg_area::clear_area(void) -{ - x_ = y_ = 0; - w_ = paper_w_; - h_ = paper_h_; - user_sel_ = whole_; - - refresh_paper_info(); -} -void dlg_area::drag_blocks(std::vector& blocks) -{ - int l = 5; - DRAGRECT r; - - r.left = user_sel_.left; - r.top = user_sel_.top; - r.right = r.left + l; - r.bottom = r.top + l; - r.pos = DRAG_POS_LT; - - blocks.clear(); - blocks.push_back(r); - OffsetRect(&r, (user_sel_.right - user_sel_.left) / 2 - l / 2, 0); r.pos = DRAG_POS_MT; - blocks.push_back(r); - OffsetRect(&r, (user_sel_.right - r.right), 0); r.pos = DRAG_POS_RT; - blocks.push_back(r); - OffsetRect(&r, 0, (user_sel_.bottom - user_sel_.top) / 2 - l / 2); r.pos = DRAG_POS_RM; - blocks.push_back(r); - OffsetRect(&r, 0, (user_sel_.bottom - r.bottom)); r.pos = DRAG_POS_RB; - blocks.push_back(r); - OffsetRect(&r, -((user_sel_.right - user_sel_.left) / 2 - l / 2), 0); r.pos = DRAG_POS_MB; - blocks.push_back(r); - OffsetRect(&r, user_sel_.left - r.left, 0); r.pos = DRAG_POS_LB; - blocks.push_back(r); - OffsetRect(&r, 0, -((user_sel_.bottom - user_sel_.top) / 2 - l / 2)); r.pos = DRAG_POS_LM; - blocks.push_back(r); -} -float dlg_area::pos_2_area(int val, bool x) -{ - float r = x ? (float)(val - whole_.left) : (float)(val - whole_.top); - - r *= ratio_; - if (unit_ == PAPER_UNIT_INCH) - r = dlg_area::mm_2_inches(r); - else if (unit_ == PAPER_UNIT_PIXEL) - r = dlg_area::mm_2_pixel(r, dpi_); - - return r; -} -void dlg_area::valid_x(int& x, bool left) -{ - if (left) - { - if (x < whole_.left) - x = whole_.left; - if (x > user_sel_.right - dlg_area::area_min_pixel) - x = user_sel_.right - dlg_area::area_min_pixel; - } - else - { - if (x > whole_.right) - x = whole_.right; - if (x < user_sel_.left + dlg_area::area_min_pixel) - x = user_sel_.left + dlg_area::area_min_pixel; - } -} -void dlg_area::valid_y(int& y, bool top) -{ - if (top) - { - if (y < whole_.top) - y = whole_.top; - if (y > user_sel_.bottom - dlg_area::area_min_pixel) - y = user_sel_.bottom - dlg_area::area_min_pixel; - } - else - { - if (y > whole_.bottom) - y = whole_.bottom; - if (y < user_sel_.top + dlg_area::area_min_pixel) - y = user_sel_.top + dlg_area::area_min_pixel; - } -} - -void dlg_area::on_unit_changed(HWND wnd) -{ - wchar_t text[80] = { 0 }; - - GetWindowTextW(wnd, text, _countof(text) - 1); - if (wcsstr(text, L"mm")) - { - if (unit_ != PAPER_UNIT_MM) - { - to_unit(PAPER_UNIT_MM); - } - } - else if (wcsstr(text, L"inch")) - { - if (unit_ != PAPER_UNIT_INCH) - { - to_unit(PAPER_UNIT_INCH); - } - } - else - { - if (unit_ != PAPER_UNIT_PIXEL) - { - to_unit(PAPER_UNIT_PIXEL); - } - } -} -void dlg_area::on_paint(HDC hdc) -{ - HBRUSH brsh_all = CreateSolidBrush(RGB(192, 192, 192)), - brsh_drag = CreateSolidBrush(RGB(255, 0, 0)), - brsh_sel = CreateSolidBrush(RGB(255, 255, 255)); - HPEN pen_border = CreatePen(PS_SOLID, 1, RGB(0, 255, 0)), - pen_ruler = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)), - pen_old = (HPEN)SelectObject(hdc, pen_border); - int step = 3, minor = 3, major = 5, count = 1, len = 0; - - FillRect(hdc, &whole_, brsh_all); - FillRect(hdc, &user_sel_, brsh_sel); - Rectangle(hdc, user_sel_.left, user_sel_.top, user_sel_.right, user_sel_.bottom); - SelectObject(hdc, pen_ruler); - for (int i = whole_.left + step; i < whole_.right; i += step) - { - ++count; - len = (count % 5) == 0 ? major : minor; - MoveToEx(hdc, i, whole_.top, NULL); - LineTo(hdc, i, whole_.top + len); - MoveToEx(hdc, i, whole_.bottom, NULL); - LineTo(hdc, i, whole_.bottom - len); - } - count = 1; - for (int i = whole_.top + step; i < whole_.bottom; i += step) - { - ++count; - len = (count % 5) == 0 ? major : minor; - MoveToEx(hdc, whole_.left, i, NULL); - LineTo(hdc, whole_.left + len, i); - MoveToEx(hdc, whole_.right, i, NULL); - LineTo(hdc, whole_.right - len, i); - } - - std::vector r; - drag_blocks(r); - for(size_t i = 0; i < r.size(); ++i) - FillRect(hdc, &r[i], brsh_drag); - - SelectObject(hdc, pen_old); - DeleteObject(pen_border); - DeleteObject(pen_ruler); - DeleteObject(brsh_all); - DeleteObject(brsh_sel); - DeleteObject(brsh_drag); -} -void dlg_area::on_mouse_move(DWORD key, int x, int y) -{ - if (key == MK_LBUTTON) - { - if (drag_ == DRAG_POS_NONE) - return; - - float dif = .0f; - - SetCursor(LoadCursorW(NULL, cursor_)); - if (drag_ == DRAG_POS_LT) - { - valid_x(x, true); - valid_y(y, true); - user_sel_.left = x; - user_sel_.top = y; - dif = x_; - x_ = pos_2_area(x, true); - w_ -= x_ - dif; - dif = y_; - y_ = pos_2_area(y, false); - h_ -= y_ - dif; - } - else if (drag_ == DRAG_POS_MT) - { - valid_y(y, true); - user_sel_.top = y; - dif = y_; - y_ = pos_2_area(y, false); - h_ -= y_ - dif; - } - else if(drag_ == DRAG_POS_RT) - { - valid_x(x, false); - valid_y(y, true); - user_sel_.right = x; - user_sel_.top = y; - w_ = pos_2_area(x, true) - x_; - if (x_ + w_ > paper_w_) - w_ = paper_w_ - x_; - dif = y_; - y_ = pos_2_area(y, false); - h_ -= y_ - dif; - } - else if (drag_ == DRAG_POS_LM) - { - valid_x(x, true); - user_sel_.left = x; - dif = x_; - x_ = pos_2_area(x, true); - w_ -= x_ - dif; - } - else if (drag_ == DRAG_POS_RM) - { - valid_x(x, false); - user_sel_.right = x; - w_ = pos_2_area(x, true) - x_; - if (x_ + w_ > paper_w_) - w_ = paper_w_ - x_; - } - else if (drag_ == DRAG_POS_LB) - { - valid_x(x, true); - valid_y(y, false); - user_sel_.left = x; - user_sel_.bottom = y; - dif = x_; - x_ = pos_2_area(x, true); - w_ -= x_ - dif; - h_ = pos_2_area(y, false) - y_; - } - else if (drag_ == DRAG_POS_MB) - { - valid_y(y, false); - user_sel_.bottom = y; - h_ = pos_2_area(y, false) - y_; - if (y_ + h_ > paper_h_) - h_ = paper_h_ - y_; - } - else if (drag_ == DRAG_POS_RB) - { - valid_x(x, false); - valid_y(y, false); - user_sel_.right = x; - user_sel_.bottom = y; - w_ = pos_2_area(x, true) - x_; - if (x_ + w_ > paper_w_) - w_ = paper_w_ - x_; - h_ = pos_2_area(y, false) - y_; - if (y_ + h_ > paper_h_) - h_ = paper_h_ - y_; - } - else if (drag_ == DRAG_POS_MOVE) - { - x += move_.x; - y += move_.y; - OffsetRect(&user_sel_, x - user_sel_.left, y - user_sel_.top); - if (user_sel_.left < whole_.left) - OffsetRect(&user_sel_, whole_.left - user_sel_.left, 0); - if (user_sel_.right > whole_.right) - OffsetRect(&user_sel_, whole_.right - user_sel_.right, 0); - if (user_sel_.top < whole_.top) - OffsetRect(&user_sel_, 0, whole_.top - user_sel_.top); - if (user_sel_.bottom > whole_.bottom) - OffsetRect(&user_sel_, 0, whole_.bottom - user_sel_.bottom); - x_ = pos_2_area(user_sel_.left, true); - if (x_ + w_ > paper_w_) - x_ = paper_w_ - w_; - y_ = pos_2_area(user_sel_.top, false); - if (y_ + h_ > paper_h_) - y_ = paper_h_ - h_; - } - - refresh_paper_info(); - InvalidateRect(hwnd(), &whole_, FALSE); - return; - } - - POINT pt = { x, y }; - std::vector r; - bool handled = false; - - drag_blocks(r); - for (size_t i = 0; i < r.size(); ++i) - { - if (PtInRect(&r[i], pt)) - { - handled = true; - if (r[i].pos == DRAG_POS_LT || r[i].pos == DRAG_POS_RB) - cursor_ = IDC_SIZENWSE; - else if(r[i].pos == DRAG_POS_RT || r[i].pos == DRAG_POS_LB) - cursor_ = IDC_SIZENESW; - else if(r[i].pos == DRAG_POS_MT || r[i].pos == DRAG_POS_MB) - cursor_ = IDC_SIZENS; - else - cursor_ = IDC_SIZEWE; - - drag_ = r[i].pos; - SetCursor(LoadCursor(NULL, cursor_)); - break; - } - } - if (!handled) - { - if (PtInRect(&user_sel_, pt)) - { - drag_ = DRAG_POS_MOVE; - cursor_ = IDC_SIZEALL; - SetCursor(LoadCursor(NULL, cursor_)); - } - else - { - drag_ = DRAG_POS_NONE; - cursor_ = NULL; - } - } -} -void dlg_area::on_lbutton_down(int x, int y) -{ - move_.x = user_sel_.left - x; - move_.y = user_sel_.top - y; - if (cursor_) - SetCursor(LoadCursorW(NULL, cursor_)); - SetCapture(hwnd()); -} -void dlg_area::on_lbutton_up(int x, int y) -{ - drag_ = DRAG_POS_NONE; - cursor_ = NULL; - ReleaseCapture(); -} - - -void dlg_area::set_paper(const wchar_t* name, float width_mm, float height_mm, float dpi) -{ - wchar_t paper[40] = { 0 }; - - dpi_ = dpi; - paper_ = name; - - paper_w_0_ = width_mm; - paper_h_0_ = height_mm; - - if (unit_ == PAPER_UNIT_INCH) - { - paper_w_ = dlg_area::mm_2_inches(width_mm); - paper_h_ = dlg_area::mm_2_inches(height_mm); - } - else if (unit_ == PAPER_UNIT_PIXEL) - { - paper_w_ = dlg_area::mm_2_pixel(width_mm, dpi_); - paper_h_ = dlg_area::mm_2_pixel(height_mm, dpi_); - } - else - { - paper_w_ = width_mm; - paper_h_ = height_mm; - } - - RECT r = { 0 }; - float xr = 1.0f, - yr = 1.0f; - - GetWindowRect(get_item(IDC_STATIC_PAINT), &r); - screen_2_client(&r); - xr = paper_w_0_ / (r.right - r.left); - yr = paper_h_0_ / (r.bottom - r.top); - ratio_ = xr >= yr ? xr : yr; - - xr = paper_w_0_ / ratio_; - xr = (r.right - r.left - xr) / 2; - yr = paper_h_0_ / ratio_; - yr = (r.bottom - r.top - yr) / 2; - whole_.left = r.left + (LONG)xr; whole_.right = r.right - (LONG)xr; - whole_.top = r.top + (LONG)yr; whole_.bottom = r.bottom - (LONG)yr; - - clear_area(); -} -void dlg_area::set_area(float x, float y, float w, float h) -{ - x_ = from_mm(x); - y_ = from_mm(y); - w_ = from_mm(w); - h_ = from_mm(h); - - if (x_ > paper_w_) - { - if (w_ < paper_w_) - x_ = paper_w_ - w_; - else - x_ = 0; - } - if (w_ + x_ > paper_w_) - w_ = paper_w_ - x_; - if (y_ > paper_h_) - { - if (h_ < paper_h_) - y_ = paper_h_ - h_; - else - y_ = 0; - } - if (h_ + y_ > paper_h_) - h_ = paper_h_ - y_; - user_sel_.left = whole_.left + (LONG)(x_ / ratio_); - user_sel_.top = whole_.top + (LONG)(y_ / ratio_); - user_sel_.right = user_sel_.left + (LONG)(w_ / ratio_); - user_sel_.bottom = user_sel_.top + (LONG)(h_ / ratio_); - - refresh_paper_info(); -} -float dlg_area::x_in_mm(void) -{ - return as_mm(x_); -} -float dlg_area::y_in_mm(void) -{ - return as_mm(y_); -} -float dlg_area::w_in_mm(void) -{ - return as_mm(w_); -} -float dlg_area::h_in_mm(void) -{ - return as_mm(h_); -} diff --git a/sane/DlgArea.h b/sane/DlgArea.h deleted file mode 100644 index 1067cad..0000000 --- a/sane/DlgArea.h +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once - -#include -#include - -#include "DlgPage.h" - -// CDlgIndicator 对话框 - -class dlg_area: public dlg_base -{ - enum paper_unit - { - PAPER_UNIT_MM = 0, - PAPER_UNIT_INCH, - PAPER_UNIT_PIXEL, - }; - enum drag_pos - { - DRAG_POS_NONE = 0, - DRAG_POS_LT, - DRAG_POS_MT, - DRAG_POS_RT, - DRAG_POS_LM, - DRAG_POS_RM, - DRAG_POS_LB, - DRAG_POS_MB, - DRAG_POS_RB, - DRAG_POS_MOVE, - }; - typedef struct _drag_block : RECT - { - drag_pos pos; - }DRAGRECT; - std::wstring paper_; - paper_unit unit_; - float paper_w_0_; - float paper_h_0_; - float paper_w_; - float paper_h_; - float dpi_; - float x_; - float y_; - float w_; - float h_; - - RECT whole_; - RECT user_sel_; - float ratio_; // mm / pixel - drag_pos drag_; - POINT move_; - bool in_set_func_; - const wchar_t* cursor_; - - static int area_min_pixel; - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void handle_command(WORD code, WORD id, HANDLE ctrl); - void layout(void); - - float as_mm(float v); - float from_mm(float v); - float as_inches(float v); - float as_pixels(float v); - std::wstring format_number(float v); - void refresh_paper_info(void); - void to_unit(paper_unit unit); - void clear_area(void); - void drag_blocks(std::vector& blocks); - float pos_2_area(int val, bool x); - void valid_x(int& x, bool left); - void valid_y(int& y, bool top); - - void on_unit_changed(HWND wnd); - void on_paint(HDC hdc); - void on_mouse_move(DWORD key, int x, int y); - void on_lbutton_down(int x, int y); - void on_lbutton_up(int x, int y); - -public: - dlg_area(HWND parent); - ~dlg_area(); - - static float mm_2_pixel(float mm, float dpi); - static float mm_2_inches(float mm); - static float inches_2_pixel(float inch, float dpi); - static float inches_2_mm(float inch); - static float pixel_2_mm(float px, float dpi); - static float pixel_2_inches(float px, float dpi); - -public: - void set_paper(const wchar_t* name, float width_mm, float height_mm, float dpi); - void set_area(float x, float y, float w, float h); - float x_in_mm(void); - float y_in_mm(void); - float w_in_mm(void); - float h_in_mm(void); -}; diff --git a/sane/DlgCfgMgr.cpp b/sane/DlgCfgMgr.cpp deleted file mode 100644 index 5ff5cd0..0000000 --- a/sane/DlgCfgMgr.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// DlgIndicator.cpp: 实现文件 -// - -#include "DlgCfgMgr.h" -#include "resource.h" -#include "scanned_img.h" // for local_trans -#include "mem_dc.h" -#include "gb_json.h" - -// CDlgIndicator 对话框 - -dlg_cfg_mgr::dlg_cfg_mgr(gb::scanner_cfg* cfg, HWND parent) : cfg_(cfg), dlg_base(parent, IDD_CFG_MGR), schm_changed_(false) -{ - create(); - - std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CFG_MANAGER)); - int dif = 0; - - SetWindowTextW(hwnd(), title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_CFG_SCHEME); - set_item_text(IDC_STATIC_PAPER, title.c_str()); - set_item_fit_to_text(IDC_STATIC_PAPER); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_DEL_SELECTED); - set_item_text(IDC_BUTTON_DEL_SEL, title.c_str()); - dif = set_item_fit_to_text(IDC_BUTTON_DEL_SEL); - if (dif) - offset_item(IDC_BUTTON_DEL_SEL, -dif, 0); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_DEL_ALL); - set_item_text(IDC_BUTTON_DEL_ALL, title.c_str()); - set_item_fit_to_text(IDC_BUTTON_DEL_ALL); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_CFG_CONTENT); - set_item_text(IDC_STATIC_SKETCH, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_OK); - set_item_text(IDOK, title.c_str()); -} -dlg_cfg_mgr::~dlg_cfg_mgr() -{ -} - - -BOOL dlg_cfg_mgr::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - wchar_t text[40] = { 0 }; - BOOL ret = TRUE; - - switch (msg) - { - case WM_INITDIALOG: - on_init_dlg(); - UpdateWindow(hwnd()); - break; - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - case WM_NOTIFY: - handle_notify(wp, (LPNMHDR)lp); - break; - case WM_PAINT: - { - PAINTSTRUCT ps = { 0 }; - HDC hdc = BeginPaint(hwnd(), &ps); - { - compatible_dc dc(hdc); - on_paint(dc.get_dc()); - } - EndPaint(hwnd(), &ps); - } - break; - default: - ret = FALSE; - } - return ret; -} -void dlg_cfg_mgr::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - wchar_t cls[128] = { 0 }; - - GetClassNameW((HWND)ctrl, cls, _countof(cls) - 1); - if (IS_BUTTON(cls)) - { - if (code == BN_CLICKED) - { - if (id == IDOK || id == IDCANCEL) - quit_modal(id); - else if (id == IDC_BUTTON_DEL_SEL) - on_del_selected(); - else if (id == IDC_BUTTON_DEL_ALL) - on_del_all(); - } - } - else if (IS_EDIT(cls)) - { - //if (code == EN_SETFOCUS) - // label_edit_ = (HWND)ctrl; - } -} -void dlg_cfg_mgr::handle_notify(UINT id, LPNMHDR pnhdr) -{ - if (id == IDC_LIST1) - { - if (pnhdr->code == LVN_BEGINLABELEDITW) - { - LPNMLVDISPINFOW pdisp = (LPNMLVDISPINFOW)pnhdr; - - label_ = pdisp->item.pszText ? pdisp->item.pszText : L""; - } - else if (pnhdr->code == LVN_ENDLABELEDITW) - { - LPNMLVDISPINFOW pdisp = (LPNMLVDISPINFOW)pnhdr; - - if (pdisp->item.pszText && label_ != pdisp->item.pszText) - { - ListView_SetItemText(get_item(IDC_LIST1), pdisp->item.iItem, pdisp->item.iSubItem, pdisp->item.pszText); - - if (cfg_) - { - if (!cfg_->rename_scheme(local_trans::u2a(label_.c_str(), CP_UTF8).c_str(), local_trans::u2a(pdisp->item.pszText, CP_UTF8).c_str())) - { - std::wstring input(pdisp->item.pszText); - - input += L" " + local_trans::lang_trans_between_hz936(CONST_STRING_ALREADY_EXISTS); - ::MessageBoxW(hwnd(), input.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_RE_INPUT).c_str(), MB_OK | MB_ICONINFORMATION); - dlg_base::list_set_item_text(get_item(IDC_LIST1), pdisp->item.iItem, 0, label_.c_str()); - } - } - } - } - else if (pnhdr->code == LVN_ITEMCHANGED) - { - LPNMLISTVIEW pv = (LPNMLISTVIEW)pnhdr; - if ((pv->uNewState & LVIS_SELECTED) && (pv->uOldState & LVIS_SELECTED) == 0) - on_sel_changed(pv->iItem); - } - } -} -void dlg_cfg_mgr::layout(void) -{ -} - - -void dlg_cfg_mgr::on_init_dlg(void) -{ - HWND lstwnd = get_item(IDC_LIST1); - std::vector schemes; - - cfg_->get_all_schemes(schemes); - dlg_base::list_insert_column(lstwnd, local_trans::lang_trans_between_hz936(CONST_STRING_CFG_NAME).c_str(), 270); - for (size_t i = 1; i < schemes.size(); ++i) // 0 is default scheme - { - dlg_base::list_insert_item(lstwnd, local_trans::a2u(schemes[i].c_str(), CP_UTF8).c_str()); - } -} -void dlg_cfg_mgr::on_paint(HDC hdc) -{ -} -void dlg_cfg_mgr::on_sel_changed(int sel) -{ - std::wstring name(dlg_base::list_get_text(get_item(IDC_LIST1), sel)); - gb::sane_config_schm* schm = cfg_->get_scheme(local_trans::u2a(name.c_str(), CP_UTF8).c_str()); - - name = L""; - if (schm) - { - std::string key(""), val(""); - int cnt = 1; - - if (schm->first_config(key, val)) - { - do - { - std::string v(gb::sane_config_schm::sane_option_value_2_string(&val[0], val.length(), (SANE_Value_Type)cfg_->option_value_type(key.c_str()))); - - name += std::to_wstring(cnt++) + L" - " + local_trans::a2u(cfg_->option_title(key.c_str()).c_str(), CP_UTF8) + L"\r\n "; - if (cfg_->option_value_type(key.c_str()) == SANE_TYPE_STRING) - v = local_trans::u2a(local_trans::lang_trans_between_hz936(local_trans::a2u(v.c_str(), CP_UTF8).c_str()).c_str(), CP_UTF8); - name += local_trans::a2u(v.c_str(), CP_UTF8) + L"\r\n\r\n"; - } while (schm->next_config(key, val)); - } - schm->release(); - } - dlg_base::set_item_text(IDC_EDIT1, name.c_str()); -} -void dlg_cfg_mgr::on_del_selected(void) -{ - std::vector sels; - HWND lwnd = get_item(IDC_LIST1); - bool changed = false; - - dlg_base::list_get_selected_items(lwnd, sels); - for(int i = sels.size() - 1; i >= 0; i--) - { - std::string name(local_trans::u2a(dlg_base::list_get_text(lwnd, sels[i]).c_str(), CP_UTF8)); - if (cfg_->remove_scheme(name.c_str())) - { - changed = true; - ListView_DeleteItem(lwnd, sels[i]); - schm_changed_ = true; - } - } -} -void dlg_cfg_mgr::on_del_all(void) -{ - cfg_->remove_all_schemes(); - ListView_DeleteAllItems(get_item(IDC_LIST1)); // clear list - schm_changed_ = true; - dlg_base::set_item_text(IDC_EDIT1, L""); -} -bool dlg_cfg_mgr::is_scheme_changed(void) -{ - return schm_changed_; -} diff --git a/sane/DlgCfgMgr.h b/sane/DlgCfgMgr.h deleted file mode 100644 index ef66783..0000000 --- a/sane/DlgCfgMgr.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include - -#include "DlgPage.h" - -// CDlgIndicator 对话框 -namespace gb -{ - class scanner_cfg; -} - -class dlg_cfg_mgr: public dlg_base -{ - gb::scanner_cfg* cfg_; - std::wstring label_; - bool schm_changed_; // to notify parent refreshing UI and settings - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void handle_command(WORD code, WORD id, HANDLE ctrl); - void handle_notify(UINT id, LPNMHDR pnhdr); - void layout(void); - - void on_init_dlg(void); - void on_paint(HDC hdc); - void on_sel_changed(int sel); - void on_del_selected(void); - void on_del_all(void); - -public: - dlg_cfg_mgr(gb::scanner_cfg* cfg, HWND parent); - ~dlg_cfg_mgr(); - -public: - bool is_scheme_changed(void); -}; diff --git a/sane/DlgGamma.cpp b/sane/DlgGamma.cpp deleted file mode 100644 index 6019e20..0000000 --- a/sane/DlgGamma.cpp +++ /dev/null @@ -1,825 +0,0 @@ -// DlgIndicator.cpp: 实现文件 -// - -#include "DlgGamma.h" -#include "resource.h" -#include "mem_dc.h" - -#include "scanned_img.h" - -#define MAX_KEY_POINTS 4 // not include (0, 0) and (255, 255) - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// calculator -#include -namespace calc -{ - void solve_matrix(double** a, int n, std::vector& coef) - { - int m = 0; - int i, j; - - coef.clear(); - for (j = 0; j < n; j++) { - double max = 0; - double imax = 0; - for (i = j; i < n; i++) { - if (imax < fabs(a[i][j])) { - imax = fabs(a[i][j]); - max = a[i][j];//得到各行中所在列最大元素 - m = i; - } - } - if (fabs(a[j][j]) != max) { - double b = 0; - for (int k = j; k < n + 1; k++) { - b = a[j][k]; - a[j][k] = a[m][k]; - a[m][k] = b; - } - } - for (int r = j; r < n + 1; r++) { - a[j][r] = a[j][r] / max;//让该行的所在列除以所在列的第一个元素,目的是让首元素为1 - } - for (i = j + 1; i < n; i++) { - double c = a[i][j]; - if (c == 0) continue; - for (int s = j; s < n + 1; s++) { - //double tempdata = a[i][s]; - a[i][s] = a[i][s] - a[j][s] * c;//前后行数相减,使下一行或者上一行的首元素为0 - } - } - } - for (i = n - 2; i >= 0; i--) { - for (j = i + 1; j < n; j++) { - a[i][n] = a[i][n] - a[j][n] * a[i][j]; - } - } - - for (int k = 0; k < n; k++) { - coef.push_back(a[k][n]); - } - } - int power(int m, int exp) - { - int val = 1; - for (int i = 0; i < exp; ++i) - val *= m; - - return val; - } - std::vector coefs_from_points(const std::vector& pt) - { - std::vector coef; - double** a = new double* [pt.size()]; - - for (int i = 0; i < (int)pt.size(); ++i) - a[i] = new double[pt.size() + 1]; - - for (int i = 0; i < (int)pt.size(); ++i) - { - for (int j = 0; j < (int)pt.size(); ++j) - a[i][j] = power(pt[i].x, pt.size() - j - 1); - a[i][pt.size()] = pt[i].y; - } - solve_matrix(a, pt.size(), coef); - for (int i = 0; i < (int)pt.size(); ++i) - delete[] a[i]; - delete[] a; - - return coef; - } -} - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// dlg_gamma -dlg_gamma::dlg_gamma(HWND parent, bool color) : dlg_base(parent, IDD_GAMMA), is_color_(color), bkgnd_(NULL) - , show_all_(false) -{ - std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM_TONE)); - - create(); - SetWindowTextW(hwnd(), title.c_str()); - - if (!dlg_base::is_language_pack_default_code_page()) - { - title = local_trans::lang_trans_between_hz936(CONST_STRING_TONE_SCHEME); - set_item_text(IDC_STATIC_SCHEME, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_COLOR_CHANNEL); - set_item_text(IDC_STATIC_COLOR, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_INITIALIZE); - set_item_text(IDC_BUTTON_RESET, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_INPUT); - set_item_text(IDC_STATIC_INPUT, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_OUTPUT); - set_item_text(IDC_STATIC_OUTPUT, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL); - set_item_text(IDCANCEL, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_OK); - set_item_text(IDOK, title.c_str()); - - layout(); - } -} -dlg_gamma::~dlg_gamma() -{ - DeleteObject(bkgnd_); -} - - -BOOL dlg_gamma::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - wchar_t text[40] = { 0 }; - BOOL ret = TRUE; - - switch (msg) - { - case WM_INITDIALOG: - on_init_dlg(); - UpdateWindow(hwnd()); - break; - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - case WM_PAINT: - { - PAINTSTRUCT ps = { 0 }; - HDC hdc = BeginPaint(hwnd(), &ps); - { - compatible_dc dc(hdc); - on_paint(dc.get_dc()); - } - EndPaint(hwnd(), &ps); - } - break; - case WM_MOUSEMOVE: - on_mouse_move(wp, LOWORD(lp), HIWORD(lp)); - break; - case WM_LBUTTONDOWN: - on_lbutton_down(LOWORD(lp), HIWORD(lp)); - break; - case WM_LBUTTONUP: - on_lbutton_up(LOWORD(lp), HIWORD(lp)); - break; - default: - ret = FALSE; - } - return ret; -} -void dlg_gamma::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - if (code == BN_CLICKED) - { - if (id == IDC_BUTTON_RESET) - { - init_curve(cur_, cur_->clr); - InvalidateRect(hwnd(), NULL, FALSE); - } - else - { - quit_modal(id); - } - } - else if (code == EN_CHANGE) - { - if (id == IDC_EDIT_INPUT) - { - wchar_t val[40] = { 0 }; - int y = 0; - - GetDlgItemTextW(hwnd(), id, val, _countof(val) - 1); - y = _wtoi(val); - if (y < cur_->points[0].x) - SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, cur_->points[0].x, FALSE); - if (y > cur_->points[1].x) - SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, cur_->points[1].x, FALSE); - else - { - y = calc_value(y); - SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, y, FALSE); - } - } - } - else if (code == CBN_SELCHANGE) - { - on_combo_sel_changed(id, SendMessage((HWND)ctrl, CB_GETCURSEL, 0, 0)); - } -} -void dlg_gamma::layout(void) -{ - int r1 = get_width_diff_as_text_length(IDC_STATIC_SCHEME), - r21 = get_width_diff_as_text_length(IDC_STATIC_COLOR), - r22 = get_width_diff_as_text_length(IDC_BUTTON_RESET), - r31 = get_width_diff_as_text_length(IDC_STATIC_INPUT), - r32 = get_width_diff_as_text_length(IDC_STATIC_OUTPUT), - r33 = get_width_diff_as_text_length(IDCANCEL), - r34 = get_width_diff_as_text_length(IDOK), - diff = 0; - - if (diff < r1) - diff = r1; - if (diff < r21 + r22) - diff = r21 + r22; - if (diff < r31 + r32 + r33 + r34) - diff = r31 + r32 + r33 + r34; - - if (diff > 0) - { - RECT r = { 0 }; - - GetWindowRect(hwnd(), &r); - r.right += diff; - MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE); - - expand_item(IDC_STATIC_SCHEME, r1, 0); - offset_item(IDC_SCHEME, r1, 0); - expand_item(IDC_SCHEME, diff - r1, 0); - - expand_item(IDC_STATIC_COLOR, r21, 0); - offset_item(IDC_CHANNEL, r21, 0); - - expand_item(IDC_BUTTON_RESET, r22, 0); - offset_item(IDC_BUTTON_RESET, diff - r22, 0); - - expand_item(IDC_STATIC_INPUT, r31, 0); - offset_item(IDC_EDIT_INPUT, r31, 0); - - offset_item(IDC_STATIC_OUTPUT, r31, 0); - expand_item(IDC_STATIC_OUTPUT, r32, 0); - offset_item(IDC_EDIT_OUTPUT, r31 + r32, 0); - - offset_item(IDCANCEL, diff - r33, 0); - expand_item(IDCANCEL, r33, 0); - - offset_item(IDOK, diff - r34, 0); - expand_item(IDOK, r34, 0); - - expand_item(IDC_STATIC_PAINT, diff, 0); - } -} -void dlg_gamma::create_background(void) -{ - COLORREF bclr = RGB(128, 128, 128); - HDC hdc = GetWindowDC(hwnd()), - cdc = CreateCompatibleDC(hdc); - HBRUSH bkg = CreateSolidBrush(bclr); - HPEN grid = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)), - old = (HPEN)SelectObject(cdc, grid); - HBITMAP ob = NULL; - int w = paint_area_.right - paint_area_.left + 2, - h = paint_area_.bottom - paint_area_.top + 2; - RECT r = { 1, 1, w - 1, h - 1}; - - if (bkgnd_) - DeleteObject(bkgnd_); - - // create bitmap and select into DC - bkgnd_ = CreateCompatibleBitmap(hdc, w, h); - ob = (HBITMAP)SelectObject(cdc, bkgnd_); - SetBkColor(cdc, bclr); - - // background and grid - FillRect(cdc, &r, bkg); - MoveToEx(cdc, r.left, r.top, NULL); - LineTo(cdc, r.right, r.top); - LineTo(cdc, r.right, r.bottom); - LineTo(cdc, r.left, r.bottom); - LineTo(cdc, r.left, r.top); - SelectObject(cdc, old); - DeleteObject(grid); - grid = CreatePen(PS_DASH, 1, RGB(0, 0, 0)); - SelectObject(cdc, grid); - for (int i = 1; i < 6; ++i) - { - MoveToEx(cdc, r.left + i * 50, r.bottom, NULL); - LineTo(cdc, r.left + i * 50, r.top); - - MoveToEx(cdc, r.left, r.bottom - i * 50, NULL); - LineTo(cdc, r.right, r.bottom - i * 50); - } - - // default curve - MoveToEx(cdc, r.left, r.bottom, NULL); - LineTo(cdc, r.right, r.top); - - // free resource - SelectObject(cdc, old); - SelectObject(cdc, ob); - DeleteDC(cdc); - ReleaseDC(hwnd(), hdc); - - DeleteObject(bkg); - DeleteObject(grid); -} -void dlg_gamma::init_curve(GAMMACURVE* curv, COLORREF clr) -{ - curv->points.clear(); - curv->points.push_back({ 0, 0 }); - curv->points.push_back({ 255, 255 }); - curv->coefs = calc::coefs_from_points(curv->points); - curv->drag = -1; - curv->left = 0; - curv->right = 1; - curv->clr = clr; -} -int dlg_gamma::add_drag_point(int x, int y) -{ - int ind = -1; - - if (cur_->points.size() < MAX_KEY_POINTS + 2) - { - for (int i = 2; i < (int)cur_->points.size(); ++i) - { - if (x < cur_->points[i].x) - { - cur_->points.insert(cur_->points.begin() + i, { x, calc_value(x) }); - ind = i; - cur_->coefs = calc::coefs_from_points(cur_->points); - break; - } - else if (x == cur_->points[i].x) - { - ind = i; - break; - } - } - if (ind == -1) - { - ind = cur_->points.size(); - cur_->points.push_back({ x, calc_value(x) }); - cur_->coefs = calc::coefs_from_points(cur_->points); - } - cur_->left = ind - 1; - cur_->right = ind + 1; - if (cur_->left == 1) - cur_->left = 0; - if (cur_->right >= (int)cur_->points.size()) - cur_->right = 1; - } - else - { - for (int i = 2; i < (int)cur_->points.size(); ++i) - { - if (x == cur_->points[i].x) - { - ind = i; - cur_->left = ind - 1; - cur_->right = ind + 1; - if (cur_->left == 1) - cur_->left = 0; - if (cur_->right >= (int)cur_->points.size()) - cur_->right = 1; - break; - } - } - } - cur_->drag = ind; - - return ind; -} -BYTE dlg_gamma::calc_value(BYTE x) -{ - double y = .0f; - for(int j = 0; j < (int)cur_->points.size(); ++j) - y += cur_->coefs[j] * calc::power(x, cur_->points.size() - j - 1); - - if (y > 255.0f) - y = 255.0f; - if (y < .0f) - y = .0f; - - bool upper = cur_->points[1].y > cur_->points[0].y; - if (y < cur_->points[!upper].y) - y = cur_->points[!upper].y; - if (y > cur_->points[upper].y) - y = cur_->points[upper].y; - - return (BYTE)(y + .5f); -} -bool dlg_gamma::is_adjacent(POINT p1, POINT p2) -{ - bool neighbour = abs(p1.x - p2.x) <= 3 && abs(p1.y - p2.y) <= 3; - - return neighbour; -} -bool dlg_gamma::hit_test(int* x, int* y) -{ - for (int i = 2; i < (int)cur_->points.size(); ++i) - { - POINT pt = { *x, *y }; - if (is_adjacent(pt, cur_->points[i])) - { - *x = cur_->points[i].x; - *y = cur_->points[i].y; - return true; - } - } - - - int val = calc_value(*x), tolerant = 3; - bool hit = false; - - if (abs(val - *y) < tolerant) - { - *y = val; - hit = true; - } - else - { - int l = *x - tolerant, - u = *x + tolerant; - if (l < 0) - l = 0; - if (u > 255) - u = 255; - for (; l <= u; ++l) - { - val = calc_value(l); - if (abs(val - *y) < tolerant) - { - hit = true; - *x = l; - *y = val; - break; - } - } - } - - return hit; -} -void dlg_gamma::draw_ellipse(HDC hdc, POINT center, int xl, int yl) -{ - center.x += paint_area_.left; - center.y = paint_area_.bottom - center.y; - - HRGN rgn = CreateEllipticRgn(center.x - xl, center.y - yl, center.x + xl, center.y + yl); - HBRUSH brsh = CreateSolidBrush(RGB(255, 0, 255)); - FillRgn(hdc, rgn, brsh); - DeleteObject(brsh); - DeleteObject(rgn); -} -void dlg_gamma::draw_current_curve(HDC hdc) -{ - MoveToEx(hdc, paint_area_.left + cur_->points[0].x, paint_area_.bottom - cur_->points[0].y, NULL); - for (int i = 0; i < 256; ++i) - { - int y = calc_value(i); - LineTo(hdc, paint_area_.left + i, paint_area_.bottom - y); - } -} - -void dlg_gamma::on_init_dlg(void) -{ - HWND combo = get_item(IDC_SCHEME); - - GetWindowRect(get_item(IDC_STATIC_PAINT), &paint_area_); - screen_2_client(&paint_area_); - paint_area_.right = paint_area_.left + 255; - paint_area_.bottom = paint_area_.top + 255; - create_background(); - - init_curve(&rgb_gray_); - init_curve(&red_, RGB(255, 0, 0)); - init_curve(&green_, RGB(0, 255, 0)); - init_curve(&blue_, RGB(0, 0, 255)); - - std::wstring lang(local_trans::lang_trans_between_hz936(CONST_STRING_CUSTOM)); - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - lang = local_trans::lang_trans_between_hz936(CONST_STRING_NEG_PHOTO) + L" (RGB)"; - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - lang = local_trans::lang_trans_between_hz936(CONST_STRING_COLOR_NEG_PHOTO) + L" (RGB)"; - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - lang = local_trans::lang_trans_between_hz936(CONST_STRING_DARKER) + L" (RGB)"; - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - lang = local_trans::lang_trans_between_hz936(CONST_STRING_BRIGHTER) + L" (RGB)"; - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - SendMessage(combo, CB_SETCURSEL, 0, 0); - - combo = get_item(IDC_CHANNEL); - if (is_color_) - { - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)L"RGB"); - lang = local_trans::lang_trans_between_hz936(CONST_STRING_RED); - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - lang = local_trans::lang_trans_between_hz936(CONST_STRING_GREEN); - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - lang = local_trans::lang_trans_between_hz936(CONST_STRING_BLUE); - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - } - else - { - lang = local_trans::lang_trans_between_hz936(CONST_STRING_GRAY); - SendMessageW(combo, CB_ADDSTRING, 0, (LPARAM)&lang[0]); - } - SendMessage(combo, CB_SETCURSEL, 0, 0); - cur_ = &rgb_gray_; - - SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, 0, FALSE); - SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, 0, FALSE); -} -void dlg_gamma::on_paint(HDC hdc) -{ - HPEN pen = CreatePen(PS_SOLID, 1, cur_->clr), - drag = CreatePen(PS_SOLID, 1, RGB(255, 0, 255)), - old = (HPEN)SelectObject(hdc, pen); - HDC cdc = CreateCompatibleDC(hdc); - HBITMAP ob = (HBITMAP)SelectObject(cdc, bkgnd_); - - BitBlt(hdc, paint_area_.left - 1, paint_area_.top - 1, paint_area_.right - paint_area_.left + 2, paint_area_.bottom - paint_area_.top + 2, - cdc, 0, 0, SRCCOPY); - SelectObject(cdc, ob); - DeleteDC(cdc); - - if (show_all_) - { - GAMMACURVE* prev = cur_; - HPEN now = NULL; - - cur_ = &red_; - now = CreatePen(PS_SOLID, 1, cur_->clr); - SelectObject(hdc, now); - draw_current_curve(hdc); - - cur_ = &green_; - SelectObject(hdc, old); - DeleteObject(now); - now = CreatePen(PS_SOLID, 1, cur_->clr); - SelectObject(hdc, now); - draw_current_curve(hdc); - - cur_ = &blue_; - SelectObject(hdc, old); - DeleteObject(now); - now = CreatePen(PS_SOLID, 1, cur_->clr); - SelectObject(hdc, now); - draw_current_curve(hdc); - - SelectObject(hdc, pen); - DeleteObject(now); - cur_ = prev; - } - else - draw_current_curve(hdc); - SelectObject(hdc, drag); - - for (int i = 0; i < (int)cur_->points.size(); ++i) - { - draw_ellipse(hdc, cur_->points[i], 3, 3); - } - SelectObject(hdc, old); - - DeleteObject(pen); -} -void dlg_gamma::on_mouse_move(DWORD key, int x, int y) -{ - POINT pt = { x, y }; - - if (PtInRect(&paint_area_, pt)) - { - x -= paint_area_.left; - y = paint_area_.bottom - y; - if (key == MK_LBUTTON && cur_->drag != -1) - { - if (x <= cur_->points[cur_->left].x) - x = cur_->points[cur_->left].x + 1; - else if (x >= cur_->points[cur_->right].x) - x = cur_->points[cur_->right].x - 1; - cur_->points[cur_->drag].x = x; - cur_->points[cur_->drag].y = y; - cur_->coefs = calc::coefs_from_points(cur_->points); - InvalidateRect(hwnd(), NULL, FALSE); - } - else if (key == MK_CONTROL) - { - y = calc_value(x); - pt.y = paint_area_.bottom - y; - ClientToScreen(hwnd(), &pt); - SetCursorPos(pt.x, pt.y); - } - SetDlgItemInt(hwnd(), IDC_EDIT_INPUT, x, FALSE); - SetDlgItemInt(hwnd(), IDC_EDIT_OUTPUT, y, FALSE); - } -} -void dlg_gamma::on_lbutton_down(int x, int y) -{ - x -= paint_area_.left; - y = paint_area_.bottom - y; - if (hit_test(&x, &y)) - { - if(add_drag_point(x, y) != -1) - SetCapture(hwnd()); - } -} -void dlg_gamma::on_lbutton_up(int x, int y) -{ - cur_->drag = -1; - cur_->left = 0; - cur_->right = 1; - ReleaseCapture(); -} -void dlg_gamma::on_combo_sel_changed(int id, int sel) -{ - show_all_ = false; - if (id == IDC_SCHEME) - { - if (sel == 1) - { - cur_ = &rgb_gray_; - init_curve(cur_); - cur_->points.clear(); - cur_->points.push_back({ 0, 255 }); - cur_->points.push_back({ 255, 0 }); - cur_->coefs = calc::coefs_from_points(cur_->points); - } - else if (sel == 2) - { - show_all_ = true; - cur_ = &red_; - init_curve(cur_, cur_->clr); - cur_->points.clear(); - cur_->points.push_back({ 33, 255 }); - cur_->points.push_back({ 185, 0 }); - cur_->points.push_back({ 119, 127 }); - cur_->coefs = calc::coefs_from_points(cur_->points); - - cur_ = &green_; - init_curve(cur_, cur_->clr); - cur_->points.clear(); - cur_->points.push_back({ 28, 255 }); - cur_->points.push_back({ 132, 0 }); - cur_->points.push_back({ 77, 127 }); - cur_->coefs = calc::coefs_from_points(cur_->points); - - cur_ = &blue_; - init_curve(cur_, cur_->clr); - cur_->points.clear(); - cur_->points.push_back({ 25, 255 }); - cur_->points.push_back({ 108, 0 }); - cur_->points.push_back({ 60, 127 }); - cur_->coefs = calc::coefs_from_points(cur_->points); - - cur_ = &red_; - } - else if (sel == 3) - { - cur_ = &rgb_gray_; - init_curve(cur_); - cur_->points.push_back({ 130, 101 }); - cur_->coefs = calc::coefs_from_points(cur_->points); - } - else if (sel == 4) - { - cur_ = &rgb_gray_; - init_curve(cur_); - cur_->points.push_back({ 103, 125 }); - cur_->coefs = calc::coefs_from_points(cur_->points); - } - InvalidateRect(hwnd(), NULL, FALSE); - } - else if (id == IDC_CHANNEL) - { - GAMMACURVE* prev = cur_, * all[] = { &rgb_gray_, &red_, &green_, &blue_ }; - - cur_ = all[sel]; - if (prev != cur_) - { - if (cur_->points.size() == 2) - { - COLORREF clr = cur_->clr; - - *cur_ = *prev; - cur_->clr = clr; - } - InvalidateRect(hwnd(), NULL, FALSE); - } - } -} - -void dlg_gamma::get_gamma(SANE_Gamma* gamma) -{ - gamma->apply_to_back = SANE_FALSE; - //if (cur_ == &rgb_gray_) - { - cur_ = &rgb_gray_; - gamma->pt_count = (SANE_Byte)(cur_->points.size() - 2); - // gamma->pt_count_r = gamma->pt_count_g = gamma->pt_count_b = 0; - for (int i = 2; i < (int)cur_->points.size(); ++i) - { - gamma->keypoint[i - 2].x = (SANE_Byte)cur_->points[i].x; - gamma->keypoint[i - 2].y = (SANE_Byte)cur_->points[i].y; - } - - for (int i = 0; i < 256; ++i) - gamma->table[i] = calc_value(i); - } - //else - { - // gamma->pt_count = 0; - - cur_ = &red_; - gamma->pt_count_r = (SANE_Byte)(cur_->points.size() - 2); - for (int i = 2; i < (int)cur_->points.size(); ++i) - { - gamma->keypoint_r[i - 2].x = (SANE_Byte)cur_->points[i].x; - gamma->keypoint_r[i - 2].y = (SANE_Byte)cur_->points[i].y; - } - for (int i = 0; i < 256; ++i) - gamma->table[i] = calc_value(i); - - cur_ = &green_; - gamma->pt_count_g = (SANE_Byte)(cur_->points.size() - 2); - for (int i = 2; i < (int)cur_->points.size(); ++i) - { - gamma->keypoint_g[i - 2].x = (SANE_Byte)cur_->points[i].x; - gamma->keypoint_g[i - 2].y = (SANE_Byte)cur_->points[i].y; - } - for (int i = 0; i < 256; ++i) - gamma->table[256 + i] = calc_value(i); - - cur_ = &blue_; - gamma->pt_count_b = (SANE_Byte)(cur_->points.size() - 2); - for (int i = 2; i < (int)cur_->points.size(); ++i) - { - gamma->keypoint_b[i - 2].x = (SANE_Byte)cur_->points[i].x; - gamma->keypoint_b[i - 2].y = (SANE_Byte)cur_->points[i].y; - } - for (int i = 0; i < 256; ++i) - gamma->table[512 + i] = calc_value(i); - } -} -void dlg_gamma::set_gamma(const SANE_Gamma* gamma, bool gray) -{ - int sel = 0; - std::wstring text(L""); - - SendMessage(get_item(IDC_CHANNEL), CB_RESETCONTENT, 0, 0); - is_color_ = !gray; - cur_ = &rgb_gray_; - init_curve(cur_); - for (int i = 0; i < gamma->pt_count; ++i) - { - POINT pt = { gamma->keypoint[i].x, gamma->keypoint[i].y }; - cur_->points.push_back(pt); - } - cur_->coefs = calc::coefs_from_points(cur_->points); - if (is_color_) - { - SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)L"RGB"); - } - else - { - text = local_trans::lang_trans_between_hz936(CONST_STRING_GRAY); - SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]); - } - - if(!gray) - { - is_color_ = true; - cur_ = &red_; - init_curve(cur_); - for (int i = 0; i < gamma->pt_count_r; ++i) - { - POINT pt = { gamma->keypoint_r[i].x, gamma->keypoint_r[i].y }; - cur_->points.push_back(pt); - } - cur_->coefs = calc::coefs_from_points(cur_->points); - - cur_ = &green_; - init_curve(cur_); - for (int i = 0; i < gamma->pt_count_g; ++i) - { - POINT pt = { gamma->keypoint_g[i].x, gamma->keypoint_g[i].y }; - cur_->points.push_back(pt); - } - cur_->coefs = calc::coefs_from_points(cur_->points); - - cur_ = &blue_; - init_curve(cur_); - for (int i = 0; i < gamma->pt_count_b; ++i) - { - POINT pt = { gamma->keypoint_b[i].x, gamma->keypoint_b[i].y }; - cur_->points.push_back(pt); - } - cur_->coefs = calc::coefs_from_points(cur_->points); - - // SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)L"RGB"); - text = local_trans::lang_trans_between_hz936(CONST_STRING_RED); - SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]); - text = local_trans::lang_trans_between_hz936(CONST_STRING_GREEN); - SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]); - text = local_trans::lang_trans_between_hz936(CONST_STRING_BLUE); - SendMessageW(get_item(IDC_CHANNEL), CB_ADDSTRING, 0, (LPARAM)&text[0]); - } - cur_ = &rgb_gray_; - sel = 0; - SendMessage(get_item(IDC_CHANNEL), CB_SETCURSEL, sel, 0); - SendMessage(get_item(IDC_SCHEME), CB_SETCURSEL, 0, 0); -} diff --git a/sane/DlgGamma.h b/sane/DlgGamma.h deleted file mode 100644 index e18ba4d..0000000 --- a/sane/DlgGamma.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include -#include - -#include "DlgPage.h" - -// CDlgIndicator 对话框 - -class dlg_gamma: public dlg_base -{ - bool is_color_; - bool show_all_; - RECT paint_area_; - HBITMAP bkgnd_; - - typedef struct _gamma_curve - { - std::vector points; - std::vector coefs; - int drag; - int left; - int right; - COLORREF clr; - }GAMMACURVE; - GAMMACURVE rgb_gray_; - GAMMACURVE red_; - GAMMACURVE green_; - GAMMACURVE blue_; - GAMMACURVE* cur_; - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void handle_command(WORD code, WORD id, HANDLE ctrl); - void layout(void); - void create_background(void); - void init_curve(GAMMACURVE* curv, COLORREF clr = RGB(255, 255, 255)); - int add_drag_point(int x, int y); - BYTE calc_value(BYTE x); - bool is_adjacent(POINT p1, POINT p2); - bool hit_test(int* x, int* y); - void draw_ellipse(HDC hdc, POINT center, int xl, int yl); - void draw_current_curve(HDC hdc); - - void on_init_dlg(void); - void on_paint(HDC hdc); - void on_mouse_move(DWORD key, int x, int y); - void on_lbutton_down(int x, int y); - void on_lbutton_up(int x, int y); - void on_combo_sel_changed(int id, int sel); - -public: - dlg_gamma(HWND parent, bool color); - ~dlg_gamma(); - -public: - void get_gamma(SANE_Gamma* gamma); - void set_gamma(const SANE_Gamma* gamma, bool gray); -}; diff --git a/sane/DlgIndicator.cpp b/sane/DlgIndicator.cpp deleted file mode 100644 index 560305a..0000000 --- a/sane/DlgIndicator.cpp +++ /dev/null @@ -1,315 +0,0 @@ -// DlgIndicator.cpp: 实现文件 -// - -#include "DlgIndicator.h" -#include "resource.h" -#include "scanned_img.h" // for local_trans - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/// dlg_choose_dev -// CDlgIndicator 对话框 - - -dlg_indicator::dlg_indicator(HWND parent) : dlg_base(parent, IDD_INDICATOR) - , papers_(0), images_(0), err_(false) -{ - create(); - SetWindowLongW(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE, GetWindowLong(GetDlgItem(hwnd_, IDC_STATIC_ERR), GWL_STYLE) | SS_OWNERDRAW); - - if (!dlg_base::is_language_pack_default_code_page()) - { - std::wstring text(local_trans::lang_trans_between_hz936(CONST_STRING_SCANNING)); - - SetWindowTextW(hwnd(), text.c_str()); - - text = local_trans::lang_trans_between_hz936(CONST_STRING_PAPER); - set_item_text(IDC_STATIC_PAPER, text.c_str()); - - text = local_trans::lang_trans_between_hz936(CONST_STRING_IMAGE); - set_item_text(IDC_STATIC_IMAGE, text.c_str()); - - text = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL); - set_item_text(IDCANCEL, text.c_str()); - - int paper = get_width_diff_as_text_length(IDC_STATIC_PAPER), - img = get_width_diff_as_text_length(IDC_STATIC_IMAGE), - btn = get_width_diff_as_text_length(IDCANCEL), - diff = paper >= img + btn ? paper : img + btn; - - if (diff > 0) - { - RECT r = { 0 }; - - GetWindowRect(hwnd(), &r); - r.right += diff; - MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE); - - expand_item(IDC_STATIC_PAPER, paper, 0); - offset_item(IDC_EDIT_PAPER, paper, 0); - - expand_item(IDC_STATIC_IMAGE, img, 0); - offset_item(IDC_EDIT_IMAGE, img, 0); - - offset_item(IDCANCEL, diff - btn, 0); - expand_item(IDCANCEL, btn, 0); - } - } -} -dlg_indicator::~dlg_indicator() -{ -} - - -BOOL dlg_indicator::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - wchar_t text[40] = { 0 }; - BOOL ret = TRUE; - - switch (msg) - { - case WM_INITDIALOG: - swprintf_s(text, _countof(text) - 1, L"%u", papers_); - SetDlgItemTextW(hwnd_, IDC_EDIT_IMAGE, text); - SetDlgItemTextW(hwnd_, IDC_EDIT_PAPER, text); - UpdateWindow(hwnd_); - break; - case WM_USB_PACKET_RECEIVED: - papers_++; - swprintf_s(text, _countof(text) - 1, L"%u", papers_); - SetDlgItemTextW(hwnd_, IDC_EDIT_PAPER, text); - UpdateWindow(hwnd_); - break; - case WM_IMAGE_RECEIVED: - images_++; - swprintf_s(text, _countof(text) - 1, L"%u", images_); - SetDlgItemTextW(hwnd_, IDC_EDIT_IMAGE, text); - UpdateWindow(hwnd_); - break; - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - case WM_DRAWITEM: - if (wp == IDC_STATIC_ERR) - { - DRAWITEMSTRUCT* ds = (DRAWITEMSTRUCT*)lp; - wchar_t text[128] = { 0 }; - HBRUSH brsh = CreateSolidBrush(GetBkColor(ds->hDC)); - - FillRect(ds->hDC, &ds->rcItem, brsh); - DeleteObject(brsh); - - GetWindowTextW(ds->hwndItem, text, _countof(text) - 1); - SetBkMode(ds->hDC, TRANSPARENT); - SetTextColor(ds->hDC, err_ ? RGB(255, 0, 0) : RGB(0, 0, 0)); - TextOutW(ds->hDC, 0, 0, text, lstrlenW(text)); - } - ret = FALSE; - break; - case WM_SCAN_WORKING: - notify_ui_event(SANE_EVENT_WORKING); - break; - case WM_SCAN_FINISHED: - if (lp) - { - std::string* str = (std::string*)wp; - std::wstring err(local_trans::a2u(str->c_str(), CP_UTF8)); - - SetDlgItemTextW(hwnd_, IDC_STATIC_ERR, err.c_str()); - delete str; - } - else - { - std::string* str = (std::string*)wp; - std::wstring txt(local_trans::lang_trans_between_hz936(CONST_STRING_TOTAL_SCANNED)); - - txt += L": " + std::to_wstring(images_); - SetDlgItemTextW(hwnd_, IDC_STATIC_ERR, txt.c_str()); - delete str; - SetTimer(hwnd_, 1, 3000, NULL); - } - SetDlgItemTextW(hwnd_, IDCANCEL, local_trans::lang_trans_between_hz936(CONST_STRING_CLOSE).c_str()); - ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_PAPER), SW_HIDE); - ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_IMAGE), SW_HIDE); - ShowWindow(GetDlgItem(hwnd_, IDC_EDIT_PAPER), SW_HIDE); - ShowWindow(GetDlgItem(hwnd_, IDC_EDIT_IMAGE), SW_HIDE); - ShowWindow(GetDlgItem(hwnd_, IDC_STATIC_ERR), SW_SHOW); - SetWindowTextW(hwnd_, local_trans::lang_trans_between_hz936(CONST_STRING_SCAN_OVER).c_str()); - UpdateWindow(hwnd_); - break; - case WM_TIMER: - if (wp == 1) - { - KillTimer(hwnd_, wp); - notify_over(false); - break; - } - default: - ret = FALSE; - break; - } - - return ret; -} -void dlg_indicator::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - if (id == IDCANCEL) - { - notify_over(true); - } -} -void dlg_indicator::notify_over(bool cancel) -{ - notify_ui_event(cancel ? SANE_EVENT_UI_CLOSE_CANCEL : SANE_EVENT_UI_CLOSE_NORMAL); -} - -HWND dlg_indicator::window(void) -{ - return hwnd_; -} -HWND dlg_indicator::parent(void) -{ - return parent_; -} -void dlg_indicator::notify_data_arrived(bool image) -{ - SendMessage(hwnd_, image ? WM_IMAGE_RECEIVED : WM_USB_PACKET_RECEIVED, 0, 0); // PostMessage 存在消息合并/遗漏的现象,改用Send -} -void dlg_indicator::notify_scan_over(const char* msg, bool err) -{ - std::string* mstr(new std::string(msg ? msg : "")); - - err_ = err; - if (!PostMessage(hwnd_, WM_SCAN_FINISHED, (WPARAM)mstr, (LPARAM)err)) - { - delete mstr; - notify_over(false); - } -} -void dlg_indicator::notify_working(void) -{ - PostMessage(hwnd_, WM_SCAN_WORKING, 0, 0); -} -// CDlgIndicator 消息处理程序 - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/// dlg_choose_dev -/// -dlg_choose_dev::dlg_choose_dev(HWND parent, const std::vector& devs) : dlg_base(parent, IDD_CHOOSE_DEV), item_(-1) -{ - create(); - - HWND lst = GetDlgItem(hwnd_, IDC_LIST1); - LV_COLUMNW col = { 0 }; - int ind = 0; - std::wstring text(local_trans::lang_trans_between_hz936(CONST_STRING_CHOOSE_DEVICE)); - - SetWindowTextW(hwnd(), text.c_str()); - ListView_SetExtendedListViewStyle(lst, ListView_GetExtendedListViewStyle(lst) | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT); - SetWindowLong(lst, GWL_STYLE, GetWindowLong(lst, GWL_STYLE) | LVS_SINGLESEL); - col.mask = LVCF_TEXT | LVCF_WIDTH; - col.cx = 180; - text = local_trans::lang_trans_between_hz936(CONST_STRING_DEVICE_NAME); - col.pszText = &text[0]; - SendMessageW(lst, LVM_INSERTCOLUMN, ind++, (LPARAM)&col); - text = local_trans::lang_trans_between_hz936(CONST_STRING_SERIAL_NUM); - col.pszText = &text[0]; - SendMessageW(lst, LVM_INSERTCOLUMN, ind++, (LPARAM)&col); - - ind = 0; - for (const auto& v: devs) - { - std::wstring n(local_trans::a2u(v.name.c_str(), CP_UTF8)), - s(local_trans::a2u(v.sn.c_str(), CP_UTF8)); - LV_ITEM item = { 0 }; - int ind = 0; - - item.mask = LVIF_TEXT; - item.pszText = &n[0]; - item.iItem = ListView_GetItemCount(lst); - ind = SendMessageW(lst, LVM_INSERTITEMW, 0, (LPARAM)&item); - - item.pszText = &s[0]; - item.iSubItem = 1; - item.iItem = ind; - SendMessageW(lst, LVM_SETITEMTEXTW, ind, (LPARAM)&item); - if (ind++ == 0) - { - item_ = 0; - ListView_SetItemState(lst, ind, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - SetFocus(lst); - } - } - - text = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL); - set_item_text(IDCANCEL, text.c_str()); - - text = local_trans::lang_trans_between_hz936(CONST_STRING_OK); - set_item_text(IDOK, text.c_str()); -} -dlg_choose_dev::~dlg_choose_dev() -{} - -BOOL dlg_choose_dev::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - wchar_t text[40] = { 0 }; - BOOL ret = TRUE; - - switch (msg) - { - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - case WM_NOTIFY: - handle_notify(wp, (LPNMHDR)lp); - break; - default: - ret = FALSE; - break; - } - - return ret; -} -void dlg_choose_dev::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - if (id == IDOK) - { - HWND lst = GetDlgItem(hwnd_, IDC_LIST1); - if (item_ >= 0 && item_ < ListView_GetItemCount(lst)) - { - wchar_t buf[128] = { 0 }; - - ListView_GetItemText(lst, item_, 0, buf, _countof(buf) - 1); - sel_ = local_trans::u2a(buf, CP_UTF8); - } - id = IDCANCEL; - } - - if (id == IDCANCEL) - { - abandon_hold_ = true; - PostMessage(hwnd_, 0, 0, 0); - } -} -void dlg_choose_dev::handle_notify(UINT id, LPNMHDR pnhdr) -{ - if (pnhdr->hwndFrom == GetDlgItem(hwnd_, IDC_LIST1)) - { - if (pnhdr->code == LVN_ITEMCHANGED) - { - LPNMHEADER h = (LPNMHEADER)pnhdr; - item_ = h->iItem; - } - else if (pnhdr->code == NM_DBLCLK) - { - handle_command(0, IDOK, NULL); - } - } -} - -std::string dlg_choose_dev::get_selected_device(void) -{ - return sel_; -} \ No newline at end of file diff --git a/sane/DlgIndicator.h b/sane/DlgIndicator.h deleted file mode 100644 index 6c64d00..0000000 --- a/sane/DlgIndicator.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "DlgPage.h" - -// CDlgIndicator 对话框 - -class dlg_indicator : public dlg_base -{ - unsigned int papers_; - unsigned int images_; - bool err_; - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void handle_command(WORD code, WORD id, HANDLE ctrl); - void notify_over(bool cancel); - -public: - dlg_indicator(HWND parent); - ~dlg_indicator(); - -public: - HWND window(void); - HWND parent(void); - void notify_data_arrived(bool image); - void notify_scan_over(const char* msg, bool err); - void notify_working(void); -}; - -typedef struct _dev_que -{ - int id; // ID,用户选中后返回该值 - std::string name; // 设备名称 - std::string sn; // 设备序列号 -}DEVQUE; - -class dlg_choose_dev : public dlg_base -{ - std::string sel_; - int item_; - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void handle_command(WORD code, WORD id, HANDLE ctrl); - void handle_notify(UINT id, LPNMHDR pnhdr); - -public: - dlg_choose_dev(HWND parent, const std::vector& devs); - ~dlg_choose_dev(); - -public: - std::string get_selected_device(void); -}; \ No newline at end of file diff --git a/sane/DlgInput.cpp b/sane/DlgInput.cpp deleted file mode 100644 index 602bb60..0000000 --- a/sane/DlgInput.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// DlgIndicator.cpp: 实现文件 -// - -#include "DlgInput.h" -#include "resource.h" -#include "scanned_img.h" // for local_trans -#include "mem_dc.h" -#include "gb_json.h" - -// CDlgIndicator 对话框 - -dlg_input::dlg_input(HWND parent, const wchar_t* init_val) : dlg_base(parent, IDD_INPUT), val_(init_val ? init_val : L"") -{ - create(); - - std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_INPUT_VAL)); - - SetWindowTextW(hwnd(), title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_CANCEL); - set_item_text(IDCANCEL, title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_OK); - set_item_text(IDOK, title.c_str()); -} -dlg_input::~dlg_input() -{ -} - - -BOOL dlg_input::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - wchar_t text[40] = { 0 }; - BOOL ret = TRUE; - - switch (msg) - { - case WM_INITDIALOG: - on_init_dlg(); - UpdateWindow(hwnd()); - break; - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - default: - ret = FALSE; - } - return ret; -} -void dlg_input::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - wchar_t cls[128] = { 0 }; - - GetClassNameW((HWND)ctrl, cls, _countof(cls) - 1); - if (IS_BUTTON(cls)) - { - if (code == BN_CLICKED) - { - if (id == IDOK || id == IDCANCEL) - { - if (id == IDOK) - { - std::wstring input(dlg_base::get_item_text(IDC_EDIT1)); - - if (input.empty()) - { - MessageBoxW(hwnd(), local_trans::lang_trans_between_hz936(CONST_STRING_RE_INPUT).c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_NO_INPUT).c_str(), MB_OK | MB_ICONSTOP); - SetFocus(get_item(IDC_EDIT1)); - return; - } - - for (auto& v : no_repeats_) - { - if (v == input) - { - input += L" " + local_trans::lang_trans_between_hz936(CONST_STRING_ALREADY_EXISTS); - ::MessageBoxW(hwnd(), input.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_RE_INPUT).c_str(), MB_OK | MB_ICONINFORMATION); - SetFocus(get_item(IDC_EDIT1)); - return; - } - } - val_ = std::move(input); - } - quit_modal(id); - } - } - } - else if (IS_EDIT(cls)) - { - //if (code == EN_SETFOCUS) - // label_edit_ = (HWND)ctrl; - } -} - - -void dlg_input::on_init_dlg(void) -{ - dlg_base::set_item_text(IDC_EDIT1, val_.c_str()); -} - -void dlg_input::set_no_repeats(const std::vector& vals) -{ - no_repeats_ = vals; -} -std::wstring dlg_input::get_value(void) -{ - return val_; -} diff --git a/sane/DlgInput.h b/sane/DlgInput.h deleted file mode 100644 index 3b11497..0000000 --- a/sane/DlgInput.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "DlgPage.h" - -// CDlgIndicator 对话框 - -class dlg_input: public dlg_base -{ - std::vector no_repeats_; - std::wstring val_; - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void handle_command(WORD code, WORD id, HANDLE ctrl); - - void on_init_dlg(void); - -public: - dlg_input(HWND parent, const wchar_t* init_val); - ~dlg_input(); - -public: - void set_no_repeats(const std::vector& vals); - std::wstring get_value(void); -}; diff --git a/sane/DlgPage.cpp b/sane/DlgPage.cpp deleted file mode 100644 index b8f2912..0000000 --- a/sane/DlgPage.cpp +++ /dev/null @@ -1,1761 +0,0 @@ -// DlgIndicator.cpp: 实现文件 -// - -#include "DlgPage.h" -#include "resource.h" -#include "scanned_img.h" // for local_trans -#include "DlgArea.h" -#include "DlgGamma.h" -#include "gb_json.h" -#include "../../code_device/hgsane/sane_hg_mdw.h" // for -#include "../../sdk/include/lang/app_language.h" - -// #pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// - -static IMPLEMENT_OPTION_STRING_COMPARE(is_sane_opt); - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// dlg_base 对话框 -extern HMODULE g_my_inst; - -std::wstring dlg_base::prop_name = L"dlg_base_object_prop_name"; - -dlg_base::dlg_base(HWND parent, UINT idd) : parent_(parent), hwnd_(NULL), idd_(idd), ui_event_notify_(NULL), ui_notify_param_(NULL) -{ -} -dlg_base::~dlg_base() -{ - if (IsWindow(hwnd_)) - { - SetPropW(hwnd_, dlg_base::prop_name.c_str(), NULL); - //if (GetCurrentThreadId() == GetWindowThreadProcessId(hwnd_, NULL)) - DestroyWindow(hwnd_); - } - EnableWindow(parent_, TRUE); - BringWindowToTop(parent_); -} - -BOOL CALLBACK dlg_base::dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) -{ - if (msg == WM_INITDIALOG) - { - dlg_base* obj = (dlg_base*)lp; - - SetPropW(hwnd, dlg_base::prop_name.c_str(), (HANDLE)obj); - obj->hwnd_ = hwnd; - } - else if (msg == WM_DESTROY) - { - dlg_base* obj = (dlg_base*)GetPropW(hwnd, dlg_base::prop_name.c_str()); - SetPropW(hwnd, dlg_base::prop_name.c_str(), NULL); - - return FALSE; - } - - dlg_base *obj = (dlg_base*)GetPropW(hwnd, dlg_base::prop_name.c_str()); - BOOL ret = FALSE; - - if (obj) - { - ret = obj->handle_message(msg, wp, lp); - } - - return ret; -} - -void dlg_base::screen_2_client(HWND wnd, LPRECT r) -{ - POINT pt = { r->left, r->top }; - - ScreenToClient(wnd, &pt); - OffsetRect(r, pt.x - r->left, pt.y - r->top); -} -void dlg_base::client_2_screen(HWND wnd, LPRECT r) -{ - POINT pt = { r->left, r->top }; - - ClientToScreen(wnd, &pt); - OffsetRect(r, pt.x - r->left, pt.y - r->top); -} -bool dlg_base::get_max_size(SIZE& dst, const SIZE& src) -{ - bool changed = false; - - if (dst.cx < src.cx) - { - dst.cx = src.cx; - changed = true; - } - if (dst.cy < src.cy) - { - dst.cy = src.cy; - changed = true; - } - - return changed; -} -bool dlg_base::get_max_size(SIZE& dst, int cx, int cy) -{ - bool changed = false; - - if (dst.cx < cx) - { - dst.cx = cx; - changed = true; - } - if (dst.cy < cy) - { - dst.cy = cy; - changed = true; - } - - return changed; -} -int dlg_base::select_combo_text(HWND combo, const wchar_t* text) -{ - int ind = SendMessageW(combo, CB_SELECTSTRING, -1, (LPARAM)text), - ret = ind; - - while (ind >= 0) - { - wchar_t buf[256] = { 0 }; - GetWindowTextW(combo, buf, _countof(buf) - 1); - if (wcsicmp(buf, text) == 0) - break; - - ret = ind; - ind = SendMessageW(combo, CB_SELECTSTRING, ret, (LPARAM)text); - } - - return ret; -} -std::wstring dlg_base::get_wnd_text(HWND h) -{ - int len = GetWindowTextLengthW(h); - wchar_t* buf = new wchar_t[len + 8]; - std::wstring ret(L""); - - memset(buf, 0, (len + 8) * 2); - GetWindowTextW(h, buf, len + 2); - ret = buf; - delete[] buf; - - return std::move(ret); -} -bool dlg_base::is_language_pack_default_code_page(void) -{ - return lang_get_cur_code_page() == DEFAULT_CODE_PAGE; -} -std::wstring dlg_base::get_menu_text(HMENU menu, int ind) -{ - MENUITEMINFOW mi = { 0 }; - wchar_t text[128] = { 0 }; - - mi.cbSize = sizeof(mi); - mi.fMask = mi.fType = MIIM_STRING; // MFT_STRING; - mi.dwTypeData = text; - mi.cch = _countof(text) - 1; - GetMenuItemInfoW(menu, ind, MF_BYPOSITION, &mi); - - return text; -} -void dlg_base::center_window(HWND wnd, HWND parent) -{ - RECT rme = { 0 }, rp = { 0 }; - int x = 0, y = 0; - - GetWindowRect(wnd, &rme); - if (!IsWindow(parent)) - parent = GetDesktopWindow(); - GetWindowRect(parent, &rp); - x = rp.left + (RECT_W(rp) - RECT_W(rme)) / 2; - y = rp.top + (RECT_H(rp) - RECT_H(rme)) / 2; - OffsetRect(&rme, x - rme.left, y - rme.top); - MoveWindow(wnd, rme.left, rme.top, RECT_W(rme), RECT_H(rme), FALSE); -} -int dlg_base::list_insert_column(HWND list_wnd, const wchar_t* text, int cx, int ind) -{ - LVCOLUMNW col = { 0 }; - - if (ind == -1) - ind = dlg_base::list_get_column_count(list_wnd); - col.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; - col.pszText = (LPWSTR)text; - col.iSubItem = 0; - col.cx = cx; - - return ListView_InsertColumn(list_wnd, ind, &col); -} -int dlg_base::list_insert_item(HWND list_wnd, const wchar_t* text, int ind) -{ - LV_ITEMW item = { 0 }; - - if (ind == -1) - ind = dlg_base::list_get_item_count(list_wnd); - item.mask = LVIF_TEXT; - item.pszText = (PWSTR)text; - item.iItem = ind; - - return ListView_InsertItem(list_wnd, &item); -} -int dlg_base::list_get_item_count(HWND list_wnd) -{ - return ListView_GetItemCount(list_wnd); -} -int dlg_base::list_get_column_count(HWND list_wnd) -{ - return ListView_GetItemCount((HWND)ListView_GetHeader(list_wnd)); -} -std::wstring dlg_base::list_get_text(HWND list_wnd, int ind, int sub) -{ - LV_ITEMW item = { 0 }; - wchar_t text[128] = { 0 }; - - item.mask = LVIF_TEXT; - item.pszText = (PWSTR)text; - item.iItem = ind; - item.iSubItem = sub; - item.cchTextMax = _countof(text) - 1; - ListView_GetItem(list_wnd, &item); - - return text; -} -void dlg_base::list_get_selected_items(HWND list_wnd, std::vector& sels) -{ - LV_ITEMW item = { 0 }; - - item.mask = LVIF_STATE; - for (int i = 0; i < dlg_base::list_get_item_count(list_wnd); ++i) - { - item.iItem = i; - item.stateMask = LVIS_SELECTED; - ListView_GetItem(list_wnd, &item); - if (item.state & LVIS_SELECTED) - sels.push_back(i); - } -} -int dlg_base::list_set_item_text(HWND list_wnd, int item, int sub_item, const wchar_t* text) -{ - LV_ITEMW lvi = { 0 }; - - lvi.iItem = item; - lvi.iSubItem = sub_item; - lvi.pszText = (LPWSTR)text; - lvi.mask = LVIF_TEXT; - - return ListView_SetItem(list_wnd, &lvi) ? 0 : 1; -} - -BOOL dlg_base::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - return FALSE; -} -void dlg_base::on_font_changed(void) -{ - -} -void dlg_base::create(void) -{ - // InitCommonControls(); - hwnd_ = CreateDialogParamW(g_my_inst, MAKEINTRESOURCE(idd_), parent_, (DLGPROC)&dlg_base::dlg_proc, (LPARAM)this); -} -void dlg_base::notify_ui_event(int ev) -{ - if (ui_event_notify_) - ui_event_notify_(ev, this, ui_notify_param_); -} -gb::sane_config_schm* dlg_base::get_config(bool* create) -{ - gb::sane_config_schm* cfg = NULL; - - SendMessage(parent_, WM_GET_CONFIG_OBJ, (WPARAM)create, (LPARAM)&cfg); - - return cfg; -} - -void dlg_base::set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param) -{ - ui_event_notify_ = notify; - ui_notify_param_ = param; -} -HWND dlg_base::hwnd(void) -{ - return hwnd_; -} -void dlg_base::show(bool visible, bool hold) -{ - UINT cmd = visible ? SW_SHOW : SW_HIDE; - DWORD style = GetWindowLong(hwnd_, GWL_STYLE); - - if (!(style & WS_CHILD)) - { - if (visible) - { - RECT r0 = { 0 }, rp = { 0 }, rme = { 0 }; - POINT pt = { 0 }; - HWND after = HWND_TOP; - - if (IsWindow(parent_)) - { - HMONITOR mon = MonitorFromWindow(parent_, MONITOR_DEFAULTTOPRIMARY); - MONITORINFO mi = { 0 }; - - mi.cbSize = sizeof(mi); - GetMonitorInfoW(mon, &mi); - r0 = mi.rcWork; - GetWindowRect(parent_, &rp); - } - else - { - GetWindowRect(GetDesktopWindow(), &r0); - rp = r0; - after = HWND_TOPMOST; - } - GetWindowRect(hwnd_, &rme); - pt.x = rp.left + (RECT_W(rp) - RECT_W(rme)) / 2; - pt.y = rp.top + (RECT_H(rp) - RECT_H(rme)) / 2; - if (pt.x + RECT_W(rme) > r0.right) - pt.x = r0.right - RECT_W(rme); - if (pt.x < r0.left) - pt.x = r0.left; - if (pt.y + RECT_H(rme) > r0.bottom) - pt.y = r0.bottom - RECT_H(rme); - if (pt.y < r0.top) - pt.y = r0.top; - SetWindowPos(hwnd_, after, pt.x, pt.y, RECT_W(rme), RECT_H(rme), SWP_NOSIZE); - UpdateWindow(hwnd_); - } - EnableWindow(parent_, !visible); - } - ShowWindow(hwnd_, cmd); - - if (hold) - { - MSG msg = { 0 }; - BOOL ret = FALSE; - - abandon_hold_ = false; - while ((ret = GetMessageW(&msg, NULL, 0, 0))) - { - if (ret == -1 || abandon_hold_) - break; - - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - } -} -int dlg_base::do_modal(HWND parent) -{ - BOOL enable_parent = FALSE, - got = TRUE; - MSG msg = { 0 }; - - modal_exit_ = 0; - if (IsWindow(parent) && parent != GetDesktopWindow()) - { - EnableWindow(parent, FALSE); - enable_parent = TRUE; - } - - dlg_base::center_window(hwnd(), parent); - ShowWindow(hwnd(), SW_SHOW); - while ((got = GetMessage(&msg, NULL, 0, 0))) - { - if ((DWORD)got == -1) - break; - - //if (enable_parent && msg.hwnd == parent && - // msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST && - // msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) - // continue; - - TranslateMessage(&msg); - DispatchMessage(&msg); - if (modal_exit_) - break; - } - ShowWindow(hwnd(), SW_HIDE); - - if (enable_parent) - { - EnableWindow(parent, TRUE); - } - - return modal_exit_; -} -void dlg_base::quit_modal(int non_zero_code) -{ - // assert ( non_zero_code ); - modal_exit_ = non_zero_code; -} -void dlg_base::enable(bool enable) -{ - EnableWindow(hwnd_, enable); -} -void dlg_base::screen_2_client(LPRECT r) -{ - POINT pt = { r->left, r->top }; - - ScreenToClient(hwnd_, &pt); - OffsetRect(r, pt.x - r->left, pt.y - r->top); -} -void dlg_base::client_2_screen(LPRECT r) -{ - POINT pt = { r->left, r->top }; - - ClientToScreen(hwnd_, &pt); - OffsetRect(r, pt.x - r->left, pt.y - r->top); -} -HWND dlg_base::get_item(UINT id) -{ - return GetDlgItem(hwnd_, id); -} -BOOL dlg_base::set_font(HFONT font) -{ - BOOL ret = SendMessage(hwnd_, WM_SETFONT, (WPARAM)font, 1) == 0; - - if (ret) - on_font_changed(); - - return ret; -} -HFONT dlg_base::get_font(void) -{ - return (HFONT)SendMessage(hwnd_, WM_GETFONT, 0, 0); -} -int dlg_base::get_string_width(const wchar_t* str, HWND wnd) -{ - if (!wnd) - wnd = hwnd_; - - HDC hdc = GetWindowDC(wnd); - SIZE size = { 0 }; - - GetTextExtentPointW(hdc, str, lstrlenW(str), &size); - ReleaseDC(wnd, hdc); - - return size.cx; -} -bool dlg_base::get_item_rect(UINT id, LPRECT r, bool client) -{ - if (client) - return GetClientRect(GetDlgItem(hwnd_, id), r) == TRUE; - else - return GetWindowRect(GetDlgItem(hwnd_, id), r) == TRUE; -} -std::wstring dlg_base::get_item_text(UINT id) -{ - return std::move(dlg_base::get_wnd_text(get_item(id))); -} -int dlg_base::get_width_diff_as_text_length(UINT id) -{ - RECT r = { 0 }; - - get_item_rect(id, &r); - - return get_string_width(get_item_text(id).c_str()) - RECT_W(r); -} -void dlg_base::offset_item(HWND wnd, int dx, int dy) -{ - RECT r = { 0 }; - - GetWindowRect(wnd, &r); - OffsetRect(&r, dx, dy); - screen_2_client(&r); - MoveWindow(wnd, r.left, r.top, RECT_W(r), RECT_H(r), FALSE); -} -void dlg_base::offset_item(UINT id, int dx, int dy) -{ - offset_item(get_item(id), dx, dy); -} -void dlg_base::expand_item(UINT id, int dx, int dy) -{ - RECT r = { 0 }; - - get_item_rect(id, &r, false); - r.right += dx; - r.bottom += dy; - screen_2_client(&r); - MoveWindow(get_item(id), r.left, r.top, RECT_W(r), RECT_H(r), FALSE); -} -bool dlg_base::set_item_text(UINT id, const wchar_t* text) -{ - return SetWindowTextW(GetDlgItem(hwnd_, id), text) == TRUE; -} -int dlg_base::set_item_fit_to_text(UINT id) -{ - HWND wnd = get_item(id); - std::wstring text(get_item_text(id)); - RECT r = { 0 }; - int w = get_string_width(text.c_str(), wnd); - - get_item_rect(id, &r, false); - if (w > RECT_W(r) || w <= RECT_W(r) / 2) - { - if (w > RECT_W(r)) - w -= RECT_W(r); - else - w -= RECT_W(r) / 2; - expand_item(id, w, 0); - } - else - w = 0; - - return w; -} -void dlg_base::show_scroll_bar(int bar, bool show) -{ - DWORD style = GetWindowLong(hwnd(), GWL_STYLE); - if (bar == SB_VERT || bar == SB_BOTH) - { - if (show) - style |= WS_VSCROLL; - else - style &= ~WS_VSCROLL; - SetWindowLong(hwnd(), GWL_STYLE, style); - } - else if (bar == SB_HORZ || bar == SB_BOTH) - { - if (show) - style |= WS_HSCROLL; - else - style &= ~WS_HSCROLL; - SetWindowLong(hwnd(), GWL_STYLE, style); - } -} -bool dlg_base::track_mouse_hover(void) -{ - return true; - TRACKMOUSEEVENT tme = { 0 }; - - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_HOVER; - tme.dwHoverTime = HOVER_DEFAULT; - tme.hwndTrack = hwnd_; - - return TrackMouseEvent(&tme); -} - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// tooltip_wnd -tooltip_wnd::tooltip_wnd() : hwnd_(NULL), parent_(NULL) -{ -} -tooltip_wnd::~tooltip_wnd() -{ - DestroyWindow(hwnd_); -} - -bool tooltip_wnd::create(HWND parent) -{ - if (!IsWindow(hwnd_)) - { - parent_ = parent; - hwnd_ = CreateWindowExW(NULL, TOOLTIPS_CLASSW, NULL, - WS_POPUP | TTS_ALWAYSTIP | TTS_BALLOON, - CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, - parent_, NULL, - GetModuleHandle(NULL), NULL); - SetWindowPos(hwnd_, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - } - - return IsWindow(hwnd_); -} -void tooltip_wnd::enable(bool enabled) -{ - if (enabled) - { - - } - else - { - - } -} -bool tooltip_wnd::add_tool_tip_for_rect(const RECT& r, const wchar_t* tips) -{ - TTTOOLINFOW toolInfo = { 0 }; - - toolInfo.cbSize = sizeof(toolInfo) - sizeof(toolInfo.lpReserved); // TOOLTIPS_CLASSW in old style, not with member 'lpReserved' - toolInfo.hwnd = parent_; - toolInfo.uFlags = TTF_SUBCLASS; - toolInfo.lpszText = (wchar_t*)(DWORD_PTR)tips; // LPSTR_TEXTCALLBACK - WM_NOTIFY.TTN_GETDISPINFO - toolInfo.hinst = GetModuleHandle(NULL); - memcpy(&toolInfo.rect, &r, sizeof(toolInfo.rect)); - - return SendMessageW(hwnd_, TTM_ADDTOOL, 0, (LPARAM)&toolInfo) == TRUE; -} - -bool tooltip_wnd::add_tool_tip_for_ctrl(HWND ctrl, const wchar_t* tips) -{ - TTTOOLINFOW toolInfo = { 0 }; - - toolInfo.cbSize = sizeof(toolInfo) - sizeof(toolInfo.lpReserved); // TOOLTIPS_CLASSW in old style, not with member 'lpReserved' - toolInfo.hwnd = parent_; - toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; - toolInfo.uId = (UINT_PTR)ctrl; - toolInfo.lpszText = (wchar_t*)(DWORD_PTR)tips; // LPSTR_TEXTCALLBACK - WM_NOTIFY.TTN_GETDISPINFO - toolInfo.hinst = GetModuleHandle(NULL); - - return SendMessageW(hwnd_, TTM_ADDTOOL, 0, (LPARAM)&toolInfo) == TRUE; -} - -bool tooltip_wnd::remove_tool_tip_for_ctrl(HWND ctrl) -{ - TTTOOLINFOW toolInfo = { 0 }; - - toolInfo.cbSize = sizeof(toolInfo) - sizeof(toolInfo.lpReserved); // TOOLTIPS_CLASSW in old style, not with member 'lpReserved' - toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; - toolInfo.hwnd = parent_; - toolInfo.uId = (UINT_PTR)ctrl; - - return SendMessageW(hwnd_, TTM_DELTOOL, 0, (LPARAM)&toolInfo) == TRUE; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// dlg_page 对话框 -std::wstring dlg_page::property_type = L"option_type"; -std::wstring dlg_page::property_host = L"option_host_wnd"; -std::wstring dlg_page::property_size = L"option_size"; -UINT dlg_page::dyn_id_base = 3000; -int dlg_page::gap_x = 20; -int dlg_page::gap_y = 15; -int dlg_page::spin_w = 8; -int dlg_page::sb_adden = 30; - -dlg_page::dlg_page(HWND parent, const wchar_t* name - , LPSANEAPI api, SANE_Handle dev) - : dlg_base(parent, IDD_PAGE), name_(name ? name : L""), ctrl_id_(0) - , sane_(*api), dev_(dev), done_(false) - , id_custom_area_(-1), id_custom_left_(-1), id_custom_right_(-1), id_custom_top_(-1), id_custom_bottom_(-1) - , id_custom_gamma_(-1), id_paper_(-1), paper_(L"A4"), id_dpi_(-1), dpi_(200), vsb_pos_(0), hsb_pos_(0) - , vsb_(false), hsb_(false) -{ - size_.cx = size_.cy = 0; - pos_.x = 12; - pos_.y = 15; - create(); - tips_wnd_.create(hwnd()); -} -dlg_page::~dlg_page() -{ - for (auto& v : ctrls_) - DestroyWindow(v); -} - -BOOL dlg_page::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - BOOL ret = TRUE; - - switch (msg) - { - case WM_MOUSEWHEEL: - ret = on_mouse_wheel(LOWORD(wp), HIWORD(wp), LOWORD(lp), HIWORD(lp)); - break; - case WM_NOTIFY: - ret = on_notify((int)wp, (LPNMHDR)lp); - break; - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - case WM_VSCROLL: - if(vsb_) - on_vscroll(HIWORD(wp), LOWORD(wp)); - break; - case WM_HSCROLL: - if(hsb_) - on_hscroll(HIWORD(wp), LOWORD(wp)); - break; - case WM_MOUSEHOVER: - track_mouse_hover(); - on_mouse_hover(LOWORD(lp), HIWORD(lp), wp); - break; - default: - ret = FALSE; - } - - return ret; -} -void dlg_page::on_font_changed(void) -{ - HFONT font = get_font(); - LOGFONTW lf = { 0 }; -} -void dlg_page::align_second_control(bool ignore_single) -{ - int pos_2nd = 0, - xoff = 0, - cnt = 0, - prev_pos = 0, - sn = -1; - - // 1st: find the right-most position of the first control - for (auto& v : ctrls_) - { - int id = (int)GetWindowLong(v, GWL_ID); - - if (id != sn) - { - RECT r = { 0 }; - GetWindowRect(v, &r); - - if (ignore_single && cnt == 1) - { - pos_2nd = prev_pos; - } - prev_pos = pos_2nd; - sn = id; - cnt = 1; - if (r.right > pos_2nd) - pos_2nd = r.right; - } - else - cnt++; - } - - // 2nd: align the controls begin from position 2 - sn = -1; - for (auto& v : ctrls_) - { - int id = (int)GetWindowLong(v, GWL_ID); - RECT r = { 0 }; - - if (id != sn) - { - GetWindowRect(v, &r); - sn = id; - xoff = pos_2nd - r.right; - } - else - { - offset_item(v, xoff, 0); - GetWindowRect(v, &r); - screen_2_client(&r); - if (size_.cx < r.right + dlg_page::gap_x) - size_.cx = r.right + dlg_page::gap_x; - } - } -} - -HWND dlg_page::create_label(int sn, const wchar_t* title, int x, int y, SIZE size) -{ - HWND wnd = CreateWindowW(WC_STATICW, title, WS_CHILD | WS_VISIBLE, x, y, size.cx, size.cy, hwnd(), NULL, g_my_inst, NULL); - - ShowWindow(wnd, SW_SHOW); - SendMessage(wnd, WM_SETFONT, (WPARAM)get_font(), 1); - SetWindowLong(wnd, GWL_ID, dlg_page::dyn_id_base + sn); - ctrls_.push_back(wnd); - - return wnd; -} -HWND dlg_page::create_slider(int sn, int x, int y, double lower, double upper, double step, double pos, LPSIZE size, bool is_double) -{ - // lower slider upper - HWND wnd = NULL; - wchar_t limit[20] = { 0 }; - const wchar_t *fmt = is_double ? FLOAT_FORMAT : L"%d"; - int w = x, ticks_limit = is_double ? 500 : 5; - DWORD style = WS_CHILD | WS_VISIBLE | TBS_HORZ; - - if (IS_DOUBLE_EQUAL(step, 0)) - step = 1.0f; - if(is_double) - swprintf_s(limit, _countof(limit) - 1, fmt, lower); - else - swprintf_s(limit, _countof(limit) - 1, fmt, (int)lower); - size->cx = get_string_width(limit); - create_label(sn, limit, x, y, *size); - x += size->cx; - size->cx = (LONG)((upper - lower + step - 1) / step + .5f); - size->cx += 100; - size->cx /= 200; - size->cx *= 100; - if (size->cx < 100) - size->cx = 100; - if (size->cx > 200) - size->cx = 200; - if (upper > lower && size->cx / (upper - lower) < ticks_limit) - style |= TBS_NOTICKS; - else - style |= TBS_AUTOTICKS; - wnd = CreateWindowW(TRACKBAR_CLASSW, L"", style, x, y, size->cx, size->cy, hwnd(), NULL, g_my_inst, NULL); - if (is_double) - { - SendMessage(wnd, TBM_SETRANGEMIN, 1, (LPARAM)int(lower * 100.0f + .5f)); - SendMessage(wnd, TBM_SETRANGEMAX, 1, (LPARAM)int(upper * 100.0f + .5f)); - SendMessage(wnd, TBM_SETPOS, TRUE, (LPARAM)int(pos * 100.0f + .5f)); - } - else - { - SendMessage(wnd, TBM_SETRANGEMIN, 1, (LPARAM)int(lower * 1.0f + .5f)); - SendMessage(wnd, TBM_SETRANGEMAX, 1, (LPARAM)int(upper * 1.0f + .5f)); - SendMessage(wnd, TBM_SETPOS, TRUE, (LPARAM)int(pos * 1.0f + .5f)); - } - SetWindowLong(wnd, GWL_ID, dlg_page::dyn_id_base + sn); - ShowWindow(wnd, SW_SHOW); - ctrls_.push_back(wnd); - - x += size->cx; - if(is_double) - swprintf_s(limit, _countof(limit) - 1, fmt, upper); - else - swprintf_s(limit, _countof(limit) - 1, fmt, (int)upper); - size->cx = get_string_width(limit); - create_label(sn, limit, x, y, *size); - size->cx = x + size->cx - w; - - return wnd; -} -HWND dlg_page::create_edit(int sn, int x, int y, int h, int w) -{ - HWND edit = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDITW, L"", WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, x, y, w, h, hwnd(), NULL, g_my_inst, NULL); - - SetWindowLong(edit, GWL_ID, dlg_page::dyn_id_base + sn); - SendMessage(edit, WM_SETFONT, (WPARAM)get_font(), 1); - ShowWindow(edit, SW_SHOW); - ctrls_.push_back(edit); - - return edit; -} -HWND dlg_page::create_combox(int sn, int x, int y, std::vector& vals, const wchar_t* cur_val, LPSIZE size) -{ - int h = vals.size() * 2 * size->cy; - HWND wnd = NULL; - - for (int i = 0; i < (int)vals.size(); ++i) - { - if (size->cx < get_string_width(vals[i].c_str())) - size->cx = get_string_width(vals[i].c_str()); - } - - size->cx += 20; - wnd = CreateWindowW(WC_COMBOBOXW, L"", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL, x, y, size->cx, h, hwnd(), NULL, g_my_inst, NULL); - SendMessage(wnd, CB_SETDROPPEDWIDTH, size->cx, 0); - for (int i = 0; i < (int)vals.size(); ++i) - { - SendMessageW(wnd, CB_ADDSTRING, 0, (LPARAM)vals[i].c_str()); - if (vals[i] == cur_val) - SendMessageW(wnd, CB_SETCURSEL, i, 0); - } - SetWindowLong(wnd, GWL_ID, dlg_page::dyn_id_base + sn); - SendMessage(wnd, WM_SETFONT, (WPARAM)get_font(), 1); - ShowWindow(wnd, SW_SHOW); - ctrls_.push_back(wnd); - - return wnd; -} -HWND dlg_page::create_spin(int sn, HWND edit, double pos, double lower, double upper, bool is_double) -{ - RECT r = { 0 }; - HWND wnd = NULL; - - GetWindowRect(edit, &r); - screen_2_client(&r); - wnd = CreateWindowW(UPDOWN_CLASSW, L"", WS_CHILD | WS_VISIBLE | UDS_SETBUDDYINT, r.right - 1, r.top, dlg_page::spin_w, r.bottom - r.top, hwnd(), NULL, g_my_inst, NULL); - SetWindowLong(wnd, GWL_ID, dlg_page::dyn_id_base + sn); - SendMessage(wnd, WM_SETFONT, (WPARAM)get_font(), 1); - if (is_double) - { - SendMessage(wnd, UDM_SETRANGE32, WPARAM(lower * 100.f + .5f), LPARAM(upper * 100.0f + .5f)); - SendMessage(wnd, UDM_SETPOS32, 0, LPARAM(pos * 100.0f + .5f)); - } - else - { - SendMessage(wnd, UDM_SETRANGE32, (WPARAM)(int)lower, (LPARAM)(int)upper); - SendMessage(wnd, UDM_SETPOS32, 0, (LPARAM)(int)pos); - } - ShowWindow(wnd, SW_SHOW); - ctrls_.push_back(wnd); - SetPropW(wnd, dlg_page::property_host.c_str(), edit); - if(!is_double) - SendMessage(wnd, UDM_SETBUDDY, (WPARAM)edit, 0); - - return wnd; -} - -HWND dlg_page::create_control_bool(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size) -{ - bool now = *(SANE_Bool*)cur_val == SANE_TRUE ? true : false; - HWND wnd = NULL; - - text_size->cx += 18 + dlg_page::gap_x; - wnd = CreateWindowW(WC_BUTTONW, title, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, pos_.x, pos_.y, text_size->cx, text_size->cy, hwnd(), NULL, g_my_inst, NULL); - SetWindowLong(wnd, GWL_ID, dlg_page::dyn_id_base + sn); - SendMessage(wnd, WM_SETFONT, (WPARAM)get_font(), 1); - ShowWindow(wnd, SW_SHOW); - ctrls_.push_back(wnd); - if (now) - SendMessage(wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); - - return wnd; -} -HWND dlg_page::create_control_int(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size) -{ - // title: combox - // title: [slider] edit spin - HWND label = create_label(sn, title, pos_.x, pos_.y, *text_size), slider = NULL, wnd = NULL, spin = NULL; - int now = *(SANE_Int*)cur_val, - x = pos_.x, - w = 50; - SIZE size(*text_size); - wchar_t text[20] = { 0 }; - - x += text_size->cx + dlg_page::gap_x; - swprintf_s(text, _countof(text) - 1, L"%d", now); - if (desc->constraint_type == SANE_CONSTRAINT_WORD_LIST) - { - const SANE_Word *v = desc->constraint.word_list; - std::vector vals; - for (int i = 0; i < v[0]; ++i) - { - swprintf_s(text, _countof(text) - 1, L"%d", v[i + 1]); - vals.push_back(text); - } - swprintf_s(text, _countof(text) - 1, L"%d", now); - wnd = create_combox(sn, x, pos_.y, vals, text, &size); - x += size.cx; - } - else - { - int lower = 0, upper = 10000; - if (desc->constraint_type == SANE_CONSTRAINT_RANGE) - { - lower = desc->constraint.range->min; - upper = desc->constraint.range->max; - slider = create_slider(sn, x, pos_.y, lower, upper, desc->constraint.range->quant, now, &size, false); - x += size.cx + dlg_page::gap_x; - } - wnd = create_edit(sn, x, pos_.y - 2, text_size->cy, w); - x += w; - SetWindowTextW(wnd, text); - if (IsWindow(slider)) - SetPropW(slider, dlg_page::property_host.c_str(), wnd); - - spin = create_spin(sn, wnd, now, lower, upper, false); - x += dlg_page::spin_w; - } - text_size->cx = x + dlg_page::gap_x; - - return wnd; -} -HWND dlg_page::create_control_float(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size) -{ - // title: combox - // title: [slider] edit spin - HWND label = create_label(sn, title, pos_.x, pos_.y, *text_size), slider = NULL, wnd = NULL, spin = NULL; - int now = *(SANE_Int*)cur_val, - x = pos_.x, - w = 50; - SIZE size(*text_size); - wchar_t text[20] = { 0 }; - - x += text_size->cx + dlg_page::gap_x; - swprintf_s(text, _countof(text) - 1, FLOAT_FORMAT, SANE_UNFIX(*(SANE_Word*)cur_val)); - if (desc->constraint_type == SANE_CONSTRAINT_WORD_LIST) - { - const SANE_Word *v = desc->constraint.word_list; - std::vector vals; - wchar_t cur[40] = { 0 }; - for (int i = 0; i < v[0]; ++i) - { - swprintf_s(text, _countof(text) - 1, FLOAT_FORMAT, SANE_UNFIX(v[i + 1])); - vals.push_back(text); - if (v[i + 1] == *(SANE_Word*)cur_val) - wcscpy_s(cur, _countof(cur) - 1, text); - } - wnd = create_combox(sn, x, pos_.y, vals, cur, &size); - x += size.cx; - } - else - { - double lower = .0f, upper = 100.0f; - if (desc->constraint_type == SANE_CONSTRAINT_RANGE) - { - lower = SANE_UNFIX(desc->constraint.range->min); - upper = SANE_UNFIX(desc->constraint.range->max); - slider = create_slider(sn, x, pos_.y, lower, upper, SANE_UNFIX(desc->constraint.range->quant), SANE_UNFIX(*(SANE_Word*)cur_val), &size, true); - x += size.cx + dlg_page::gap_x; - } - wnd = create_edit(sn, x, pos_.y - 2, text_size->cy, w); - x += w; - SetWindowTextW(wnd, text); - if (IsWindow(slider)) - SetPropW(slider, dlg_page::property_host.c_str(), wnd); - - spin = create_spin(sn, wnd, SANE_UNFIX(*(SANE_Word*)cur_val), lower, upper, true); - x += dlg_page::spin_w; - } - text_size->cx = x + dlg_page::gap_x; - - return wnd; -} -HWND dlg_page::create_control_string(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size) -{ - HWND wnd = NULL; - int x = pos_.x; - std::wstring now(local_trans::a2u((char*)cur_val, CP_UTF8)); - - create_label(sn, title, x, pos_.y, *text_size); - x += text_size->cx + dlg_page::gap_x; - - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - std::vector vals; - const SANE_String_Const *str = desc->constraint.string_list; - SIZE size(*text_size); - - for (int i = 0; str[i]; ++i) - { - std::wstring text(local_trans::a2u(str[i], CP_UTF8)); - vals.push_back(text); - } - wnd = create_combox(sn, x, pos_.y, vals, now.c_str(), &size); - x += size.cx; - } - else - { - wnd = create_edit(sn, x, pos_.y, text_size->cy, 200); - SetWindowTextW(wnd, now.c_str()); - x += 200; - } - text_size->cx = x + dlg_page::gap_x; - - return wnd; -} -HWND dlg_page::create_control_button(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size) -{ - HWND wnd = NULL; - - return wnd; -} - -void dlg_page::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - wchar_t cls[128] = { 0 }; - - GetClassNameW((HWND)ctrl, cls, _countof(cls) - 1); - if ((IS_EDIT(cls) && code != EN_KILLFOCUS) || // for BUG-363 - (IS_COMBOX(cls) && code != CBN_SELCHANGE)) - { - return; - } - if (IS_BUTTON(cls)) - { - HWND host = (HWND)GetPropW((HWND)ctrl, dlg_page::property_host.c_str()); - if (IsWindow(host)) - { - if (id == dlg_page::dyn_id_base + id_custom_area_) - { - unsigned int size = 0; - std::string utf8(local_trans::u2a(paper_.c_str(), CP_UTF8)); - dlg_area dlg(parent_); - float x = .0f, y = .0f, w = .0f, h = .0f; - SANE_Fixed sf; - - sane_.sane_io_control_api(dev_, IO_CTRL_CODE_GET_PAPER_SIZE, &utf8[0], &size); - dlg.set_paper(paper_.c_str(), (float)(size & 0x0ffff), float(size >> 16), dpi_); - sane_.sane_control_option_api(dev_, id_custom_left_, SANE_ACTION_GET_VALUE, &sf, NULL); - x = (float)SANE_UNFIX(sf); - sane_.sane_control_option_api(dev_, id_custom_top_, SANE_ACTION_GET_VALUE, &sf, NULL); - y = (float)SANE_UNFIX(sf); - sane_.sane_control_option_api(dev_, id_custom_right_, SANE_ACTION_GET_VALUE, &sf, NULL); - w = (float)SANE_UNFIX(sf) - x; - sane_.sane_control_option_api(dev_, id_custom_bottom_, SANE_ACTION_GET_VALUE, &sf, NULL); - h = (float)SANE_UNFIX(sf) - y; - dlg.set_area(x, y, w, h); - if (dlg.do_modal(parent_) == IDOK) - { - SANE_Fixed val = SANE_FIX(dlg.x_in_mm()); - SANE_Int after = 0; - bool created = true; - gb::sane_config_schm* cfg = get_config(&created); - - sane_.sane_control_option_api(dev_, id_custom_left_, SANE_ACTION_SET_VALUE, &val, &after); - if (cfg) - cfg->config_changed(id_custom_left_, (char*)&val, sizeof(val)); - - val = SANE_FIX(dlg.y_in_mm()); - sane_.sane_control_option_api(dev_, id_custom_top_, SANE_ACTION_SET_VALUE, &val, &after); - if (cfg) - cfg->config_changed(id_custom_top_, (char*)&val, sizeof(val)); - - val = SANE_FIX(dlg.x_in_mm() + dlg.w_in_mm()); - sane_.sane_control_option_api(dev_, id_custom_right_, SANE_ACTION_SET_VALUE, &val, &after); - if (cfg) - cfg->config_changed(id_custom_right_, (char*)&val, sizeof(val)); - - val = SANE_FIX(dlg.y_in_mm() + dlg.h_in_mm()); - sane_.sane_control_option_api(dev_, id_custom_bottom_, SANE_ACTION_SET_VALUE, &val, &after); - if (cfg) - { - cfg->config_changed(id_custom_bottom_, (char*)&val, sizeof(val)); - cfg->release(); - } - } - return; - } - else if (id == dlg_page::dyn_id_base + id_custom_gamma_) - { - dlg_gamma dlg(parent_, true); - SANE_Gamma gamma = { 0 }; - unsigned int len = sizeof(gamma); - bool created = true; - - sane_.sane_io_control_api(dev_, IO_CTRL_CODE_GET_CUSTOM_GAMMA, &gamma, &len); - dlg.set_gamma(&gamma, len < 2); - if (dlg.do_modal(parent_) == IDOK) - { - len = sizeof(gamma); - dlg.get_gamma(&gamma); - sane_.sane_io_control_api(dev_, IO_CTRL_CODE_SET_CUSTOM_GAMMA, &gamma, &len); - - gb::sane_config_schm* cfg = get_config(&created); - if (cfg) - { - cfg->config_changed(id_custom_gamma_, (char*)&gamma, sizeof(gamma), true); - cfg->release(); - } - } - - return; - } - } - } - - control_action((HWND)ctrl); -} -BOOL dlg_page::on_notify(int ctrl_id, LPNMHDR pnmh) -{ - wchar_t cls[128] = { 0 }; - - pnmh->code == NM_TOOLTIPSCREATED; - GetClassNameW((HWND)pnmh->hwndFrom, cls, _countof(cls) - 1); - if (IS_TRACKBAR(cls)) - { - if (pnmh->code != NM_RELEASEDCAPTURE) - { - if (pnmh->code == NM_CUSTOMDRAW && (GetAsyncKeyState(VK_LBUTTON) & 0x8000) && GetFocus() == pnmh->hwndFrom) // drag track ... - ; - else - return FALSE; - } - } - else if (IS_UPDOWN_ARROW(cls)) - { - HWND host = (HWND)GetPropW(pnmh->hwndFrom, dlg_page::property_host.c_str()); - if (IsWindow(host) && (int)GetPropW(host, dlg_page::property_type.c_str()) == SANE_TYPE_INT) - return FALSE; - } - else if (IS_BUTTON(cls)) - return FALSE; - - control_action(pnmh->hwndFrom); - - return TRUE; -} - -void* dlg_page::value_from_ctrl(HWND ctrl, SANE_Value_Type* type) -{ - void* ret = NULL; - HWND host = (HWND)GetPropW(ctrl, dlg_page::property_host.c_str()); - wchar_t cls[40] = { 0 }; - SANE_Value_Type tp = SANE_TYPE_INT; - int(__cdecl * cmpstr)(const wchar_t*, const wchar_t*) = wcscmp; - - if (!IsWindow(host)) - host = ctrl; - tp = (SANE_Value_Type)(DWORD)GetPropW(host, dlg_page::property_type.c_str()); - if (type) - *type = tp; - GetClassNameW(ctrl, cls, _countof(cls) - 1); - if (cmpstr(cls, WC_BUTTONW) == 0) - { - if (tp == SANE_TYPE_BOOL) - { - ret = new char[sizeof(SANE_Bool)]; - *(SANE_Bool*)ret = SendMessage(ctrl, BM_GETCHECK, 0, 0) == BST_CHECKED ? SANE_TRUE : SANE_FALSE; - } - } - else if (cmpstr(cls, TRACKBAR_CLASSW) == 0) - { - if (tp == SANE_TYPE_INT) - { - ret = new char[sizeof(SANE_Int)]; - *(SANE_Int*)ret = SendMessage(ctrl, TBM_GETPOS, 0, 0); - } - else if (tp == SANE_TYPE_FIXED) - { - double pos = (double)SendMessage(ctrl, TBM_GETPOS, 0, 0); - - ret = new char[sizeof(SANE_Fixed)]; - *(SANE_Fixed*)ret = SANE_FIX(pos / 100.0f); - } - } - else if (cmpstr(cls, WC_EDITW) == 0 || cmpstr(cls, WC_COMBOBOXW) == 0) - { - int len = (int)GetPropW(host, dlg_page::property_size.c_str()); - wchar_t* buf = new wchar_t[len + 8]; - - GetWindowTextW(ctrl, buf, len + 6); - if (tp == SANE_TYPE_INT) - { - ret = new char[sizeof(SANE_Int)]; - *(SANE_Int*)ret = _wtoi(buf); - } - else if (tp == SANE_TYPE_FIXED) - { - ret = new char[sizeof(SANE_Fixed)]; - *(SANE_Fixed*)ret = SANE_FIX(_wtof(buf)); - } - else if (tp == SANE_TYPE_STRING) - { - buf[len] = 0; - std::string utf8(local_trans::u2a(buf, CP_UTF8)); - ret = new char[len + 2]; - if ((int)utf8.length() > len) - utf8.erase(len); - strcpy((char*)ret, utf8.c_str()); - ((char*)ret)[len] = 0; - } - delete[] buf; - } - else if (cmpstr(cls, UPDOWN_CLASSW) == 0) - { - if (tp == SANE_TYPE_INT) - { - ret = new char[sizeof(SANE_Int)]; - *(SANE_Int*)ret = (int)SendMessage(ctrl, UDM_GETPOS, 0, 0); - } - else if (tp == SANE_TYPE_FIXED) - { - double pos = (double)(int)SendMessage(ctrl, UDM_GETPOS32, 0, 0); - - ret = new char[sizeof(SANE_Fixed)]; - *(SANE_Fixed*)ret = SANE_FIX(pos / 100.0f); - } - } - - return ret; -} -void dlg_page::set_ctrl_value(HWND ctrl, SANE_Value_Type type, void* val, bool only_me, bool skip_ctrl) -{ - if (only_me) - { - bool finish = done_; - wchar_t cls[128] = { 0 }; - - GetClassNameW(ctrl, cls, _countof(cls) - 1); - done_ = false; - if (IS_BUTTON(cls)) - { - if (type == SANE_TYPE_BOOL) - { - DWORD id = GetWindowLong(ctrl, GWL_ID) - dlg_page::dyn_id_base; - HWND host = (HWND)GetPropW(ctrl, dlg_page::property_host.c_str()); - - if (IsWindow(host) && (id == id_custom_area_ || id == id_custom_gamma_)) - EnableWindow(ctrl, *(SANE_Bool*)val == SANE_TRUE); - else - SendMessage(ctrl, BM_SETCHECK, *(SANE_Bool*)val == SANE_TRUE ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); - } - } - else if (IS_TRACKBAR(cls)) - { - if (type == SANE_TYPE_INT) - SendMessage(ctrl, TBM_SETPOS, 1, (LPARAM)*(SANE_Int*)val); - else if (type == SANE_TYPE_FIXED) - { - double pos = SANE_UNFIX(*(SANE_Fixed*)val); - SendMessage(ctrl, TBM_SETPOS, TRUE, (LPARAM)int(pos * 100.0f + .5f)); - } - } - else if (IS_EDIT(cls) || IS_COMBOX(cls)) - { - wchar_t buf[40] = { 0 }; - std::wstring text(L""); - if (type == SANE_TYPE_INT) - { - swprintf_s(buf, _countof(buf) - 1, L"%d", *(SANE_Int*)val); - text = buf; - } - else if (type == SANE_TYPE_FIXED) - { - swprintf_s(buf, _countof(buf) - 1, FLOAT_FORMAT, SANE_UNFIX(*(SANE_Fixed*)val)); - text = buf; - } - else if (type == SANE_TYPE_STRING) - { - text = local_trans::a2u((char*)val, CP_UTF8); - } - if (IS_EDIT(cls)) - SetWindowTextW(ctrl, text.c_str()); - else - dlg_base::select_combo_text(ctrl, text.c_str()); - } - else if (IS_UPDOWN_ARROW(cls)) - { - if (type == SANE_TYPE_INT) - { - SendMessage(ctrl, UDM_SETPOS32, 0, *(SANE_Int*)val); - } - else if (type == SANE_TYPE_FIXED) - { - double pos = SANE_UNFIX(*(SANE_Fixed*)val); - } - } - done_ = finish; - } - else - { - int id = GetWindowLong(ctrl, GWL_ID); - int ind = 0; - - for (; ind < (int)ctrls_.size(); ++ind) - { - if (GetWindowLong(ctrls_[ind], GWL_ID) == id) - break; - } - for (; ind < (int)ctrls_.size(); ++ind) - { - if (GetWindowLong(ctrls_[ind], GWL_ID) != id) - break; - if (skip_ctrl && ctrl == ctrls_[ind]) - continue; - set_ctrl_value(ctrls_[ind], type, val, true); - } - } -} -void dlg_page::free_ctrl_value(void* val) -{ - if (val) - { - char* v = (char*)val; - delete[] v; - } -} -int dlg_page::find_control_ind(HWND wnd) -{ - int ind = -1; - - for (int i = 0; i < (int)ctrls_.size(); ++i) - { - if (ctrls_[i] == wnd) - { - ind = i; -break; - } - } - - return ind; -} -void dlg_page::control_action(HWND wnd) -{ - if (done_) - { - SANE_Value_Type type = (SANE_Value_Type)-1; - int id = GetWindowLong(wnd, GWL_ID); - void* val = value_from_ctrl(wnd, &type); - - if (val) - { - SANE_Int after = 0; - std::string to_v(hg_sane_middleware::option_value_2_string(type, val)); - SANE_Status statu = sane_.sane_control_option_api(dev_, id - dlg_page::dyn_id_base, SANE_ACTION_SET_VALUE, val, &after); - bool created = true; - gb::sane_config_schm* cfg = get_config(&created); - done_ = false; - if (cfg) - { - size_t len = 0; - switch (type) - { - case SANE_TYPE_BOOL: - len = sizeof(SANE_Bool); - break; - case SANE_TYPE_INT: - len = sizeof(SANE_Int); - break; - case SANE_TYPE_FIXED: - len = sizeof(SANE_Fixed); - break; - case SANE_TYPE_STRING: - len = lstrlenA((char*)val); - break; - default: - break; - } - if (len) - { - if (type == SANE_TYPE_STRING) - { - std::string def_lang(to_default_language((char*)val, nullptr)); - cfg->config_changed(id - dlg_page::dyn_id_base, &def_lang[0], def_lang.length()); - } - else - cfg->config_changed(id - dlg_page::dyn_id_base, (char*)val, len); - } - cfg->release(); - } - if (statu == SANE_STATUS_INVAL) - { - std::wstring attr(local_trans::lang_trans_between_hz936(CONST_STRING_NOT_SUPPORT_SET) + L" \"" - + local_trans::a2u(sane_.sane_get_option_descriptor_api(dev_, id - dlg_page::dyn_id_base)->title, CP_UTF8) - + L"\" " + local_trans::lang_trans_between_hz936(CONST_STRING_SET_TO_BE) + L": "), - attr_v(local_trans::a2u(to_v.c_str(), CP_UTF8)); - MessageBoxW(hwnd(), (attr + attr_v).c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_PARAMETER_ERROR).c_str(), MB_OK); - set_ctrl_value(wnd, type, val, true); - } - else - { - std::string tov(hg_sane_middleware::option_value_2_string(type, val)); - if (tov != to_v) - { - std::wstring attr(local_trans::lang_trans_between_hz936(CONST_STRING_PARAMETER_ORIGIN) + L" \"" - + local_trans::a2u(to_v.c_str(), CP_UTF8) + L"\" " - + local_trans::lang_trans_between_hz936(CONST_STRING_PARAMETER_INEXACT)), - attr_v(local_trans::a2u(tov.c_str(), CP_UTF8)); - MessageBoxW(hwnd(), (attr + attr_v).c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_PARAMETER_ADJUSTED).c_str(), MB_OK); - } - set_ctrl_value(wnd, type, val, false, !(after || statu)); - } - done_ = true; - if (id == dlg_page::dyn_id_base + id_dpi_) - { - if (type == SANE_TYPE_FIXED) - dpi_ = (float)SANE_UNFIX(*(SANE_Fixed*)val); - else - dpi_ = (float)(int)*(SANE_Int*)val; - } - else if (id == dlg_page::dyn_id_base + id_paper_) - paper_ = local_trans::a2u((char*)val, CP_UTF8); - - if (after || (statu && statu != SANE_STATUS_INVAL)) - PostMessage(parent_, WM_REFRESH_OPTION, id - dlg_page::dyn_id_base, 0); - free_ctrl_value(val); - } - } -} -BOOL dlg_page::on_mouse_wheel(WORD vkey, short delta, short x, short y) -{ - POINT pt = { x, y }; - HWND wnd = WindowFromPoint(pt); - BOOL handled = FALSE; - - if (IsWindow(wnd)) - { - wchar_t cls[128] = { 0 }; - GetClassNameW(wnd, cls, _countof(cls) - 1); - if (IS_EDIT(cls)) - { - SANE_Value_Type type = (SANE_Value_Type)(DWORD)GetPropW(wnd, dlg_page::property_type.c_str()); - if (type == SANE_TYPE_INT || type == SANE_TYPE_FIXED) - { - int s = delta < 0 ? -1 : 1; - GetWindowTextW(wnd, cls, _countof(cls) - 1); - handled = TRUE; - if (type == SANE_TYPE_INT) - swprintf_s(cls, _countof(cls) - 1, L"%d", _wtoi(cls) + 1 * s); - else - swprintf_s(cls, _countof(cls) - 1, FLOAT_FORMAT, _wtof(cls) + .01f * s); - SetWindowTextW(wnd, cls); - } - } - } - - return handled; -} -void dlg_page::on_vscroll(int pos, int sb_ev) -{ - int old = vsb_pos_; - if (sb_ev == SB_THUMBPOSITION || sb_ev == SB_THUMBTRACK) - { - vsb_pos_ = pos; - } - else if (sb_ev == SB_LINEUP || sb_ev == SB_TOP) - vsb_pos_--; - else if (sb_ev == SB_LINEDOWN || sb_ev == SB_BOTTOM) - vsb_pos_++; - else if (sb_ev == SB_PAGEUP) - vsb_pos_ -= size_view_.cy; - else if (sb_ev == SB_PAGEDOWN) - vsb_pos_ += size_view_.cy; - else - { - return; - } - - if (vsb_pos_ < 0) - vsb_pos_ = 0; - else if (vsb_pos_ > desired_size().cy - size_view_.cy + dlg_page::sb_adden) - vsb_pos_ = desired_size().cy - size_view_.cy + dlg_page::sb_adden; - - if (old != vsb_pos_) - { - ScrollWindow(hwnd(), 0, old - vsb_pos_, NULL, NULL); - SetScrollPos(hwnd(), SB_VERT, vsb_pos_, TRUE); - } -} -void dlg_page::on_hscroll(int pos, int sb_ev) -{ - int old = hsb_pos_; - if (sb_ev == SB_THUMBPOSITION || sb_ev == SB_THUMBTRACK) - { - hsb_pos_ = pos; - } - else if (sb_ev == SB_LINEUP || sb_ev == SB_TOP) - hsb_pos_--; - else if (sb_ev == SB_LINEDOWN || sb_ev == SB_BOTTOM) - hsb_pos_++; - else if (sb_ev == SB_PAGEUP) - hsb_pos_ -= size_view_.cx; - else if (sb_ev == SB_PAGEDOWN) - hsb_pos_ += size_view_.cx; - else - { - return; - } - - if (hsb_pos_ < 0) - hsb_pos_ = 0; - else if (hsb_pos_ > desired_size().cx - size_view_.cx + dlg_page::sb_adden) - hsb_pos_ = desired_size().cx - size_view_.cx + dlg_page::sb_adden; - - if (old != hsb_pos_) - { - ScrollWindow(hwnd(), old - hsb_pos_, 0, NULL, NULL); - SetScrollPos(hwnd(), SB_HORZ, hsb_pos_, TRUE); - } -} -void dlg_page::on_mouse_hover(int x, int y, int flag) -{ - POINT pt = { x, y }; - HWND ctrl = NULL; - - ClientToScreen(hwnd_, &pt); - ctrl = WindowFromPoint(pt); - if (IsWindow(ctrl)) - { - int id = GetWindowLong(ctrl, GWL_ID); - if (id > dlg_page::dyn_id_base) - { - id -= dlg_page::dyn_id_base; - const SANE_Option_Descriptor* desc = sane_.sane_get_option_descriptor_api(dev_, id); - if (desc) - { - std::wstring tips(local_trans::a2u(desc->title, CP_UTF8)); - // MessageBoxW(NULL, tips.c_str(), L"Tips", MB_OK); - } - } - } -} - -bool dlg_page::add_control(int sn, const SANE_Option_Descriptor* desc, void* cur_val) -{ - bool ret = false; - - struct - { - int sane_type; - HWND(dlg_page::* func)(int, const SANE_Option_Descriptor*, void*, const wchar_t*, LPSIZE); - }creat[] = { {SANE_TYPE_BOOL, &dlg_page::create_control_bool} - , {SANE_TYPE_INT, &dlg_page::create_control_int} - , {SANE_TYPE_FIXED, &dlg_page::create_control_float} - , {SANE_TYPE_STRING, &dlg_page::create_control_string} - , {SANE_TYPE_BUTTON, &dlg_page::create_control_button} - }; - if (strcmp(SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT, desc->name) == 0) - id_custom_left_ = sn; - else if (strcmp(SANE_STD_OPT_NAME_CUSTOM_AREA_TOP, desc->name) == 0) - id_custom_top_ = sn; - else if (strcmp(SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM, desc->name) == 0) - id_custom_bottom_ = sn; - else if (strcmp(SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT, desc->name) == 0) - id_custom_right_ = sn; - else - { - for (int i = 0; i < _countof(creat); ++i) - { - if (creat[i].sane_type == desc->type) - { - std::wstring title(local_trans::a2u(desc->title, CP_UTF8)); - HDC hdc = GetWindowDC(hwnd()); - SIZE text = { 0 }; - HWND wnd = NULL; - int pos = ctrls_.size(); - - GetTextExtentPointW(hdc, title.c_str(), title.length(), &text); - ReleaseDC(hwnd(), hdc); - wnd = (this->*creat[i].func)(sn, desc, cur_val, title.c_str(), &text); - ret = IsWindow(wnd); - if (ret) - { - if (desc->desc && *desc->desc) - tips_wnd_.add_tool_tip_for_ctrl(wnd, local_trans::a2u(desc->desc, CP_UTF8).c_str()); - SetPropW(wnd, dlg_page::property_type.c_str(), (HANDLE)creat[i].sane_type); - SetPropW(wnd, dlg_page::property_size.c_str(), (HANDLE)desc->size); - if (desc->cap & SANE_CAP_INACTIVE) - { - for (; pos < (int)ctrls_.size(); ++pos) - EnableWindow(ctrls_[pos], FALSE); - } - if (strcmp(SANE_STD_OPT_NAME_CUSTOM_AREA, desc->name) == 0) - { - // custom area ... - int w = 69; - HWND host = wnd; - std::wstring t(local_trans::lang_trans_between_hz936(CONST_STRING_SET_AREA)); - - id_custom_area_ = sn; - text.cx += dlg_page::gap_x; - wnd = CreateWindowW(WC_BUTTONW, t.c_str(), WS_CHILD | WS_VISIBLE, pos_.x + text.cx, pos_.y - 1, w, text.cy + 3, hwnd(), NULL, g_my_inst, NULL); - text.cx += w + dlg_page::gap_x; - EnableWindow(wnd, (desc->cap & SANE_CAP_INACTIVE) == 0 && *(SANE_Bool*)cur_val == SANE_TRUE); - SetWindowLong(wnd, GWL_ID, dlg_page::dyn_id_base + sn); - SendMessage(wnd, WM_SETFONT, (WPARAM)get_font(), 1); - SetPropW(wnd, dlg_page::property_host.c_str(), host); - ctrls_.push_back(wnd); - } - else if (strcmp(SANE_STD_OPT_NAME_PAPER, desc->name) == 0) - { - paper_ = local_trans::a2u((char*)cur_val, CP_UTF8); - id_paper_ = sn; - } - else if (strcmp(SANE_STD_OPT_NAME_RESOLUTION, desc->name) == 0) - { - if (desc->type == SANE_TYPE_FIXED) - dpi_ = (float)SANE_UNFIX(*(SANE_Fixed*)cur_val); - else - dpi_ = (float)(int)*(SANE_Int*)cur_val; - id_dpi_ = sn; - } - else if (strcmp(SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA, desc->name) == 0) - { - // custom gamma control ... - int w = 78; - HWND host = wnd; - std::wstring t(local_trans::lang_trans_between_hz936(CONST_STRING_SET_TONE)); - - id_custom_gamma_ = sn; - text.cx += dlg_page::gap_x; - wnd = CreateWindowW(WC_BUTTONW, t.c_str(), WS_CHILD | WS_VISIBLE, pos_.x + text.cx, pos_.y - 1, w, text.cy + 3, hwnd(), NULL, g_my_inst, NULL); - text.cx += w + dlg_page::gap_x; - EnableWindow(wnd, (desc->cap& SANE_CAP_INACTIVE) == 0 && *(SANE_Bool*)cur_val == SANE_TRUE); - SetWindowLong(wnd, GWL_ID, dlg_page::dyn_id_base + sn); - SendMessage(wnd, WM_SETFONT, (WPARAM)get_font(), 1); - SetPropW(wnd, dlg_page::property_host.c_str(), host); - ctrls_.push_back(wnd); - } - if (size_.cx < pos_.x + text.cx + 10) - size_.cx = pos_.x + text.cx + 10; - pos_.y += text.cy + dlg_page::gap_y; - } - break; - } - } - } - size_.cy = pos_.y; - size_view_ = size_; - - return ret; -} -void dlg_page::add_control_done(void) -{ - done_ = true; - align_second_control(true); -} -SIZE dlg_page::desired_size(void) -{ - return size_; -} -void dlg_page::show(void) -{ - ShowWindow(hwnd_, SW_SHOW); -} -void dlg_page::hide(void) -{ - ShowWindow(hwnd_, SW_HIDE); -} -bool dlg_page::refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val) -{ - bool found = false; - int ind = 0; - - sn += dlg_page::dyn_id_base; - for (; ind < (int)ctrls_.size(); ++ind) - { - if (GetWindowLong(ctrls_[ind], GWL_ID) == sn) - { - found = true; - break; - } - } - done_ = false; - for (; ind < (int)ctrls_.size(); ++ind) - { - if (GetWindowLong(ctrls_[ind], GWL_ID) != sn) - break; - set_ctrl_value(ctrls_[ind], desc->type, cur_val, true); - EnableWindow(ctrls_[ind], (desc->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE); - HWND host = (HWND)GetPropW(ctrls_[ind], dlg_page::property_host.c_str()); - if (IsWindow(host)) - { - BOOL checked = SendMessage(host, BM_GETCHECK, 0, 0) == BST_CHECKED; - checked &= (desc->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE; - if (sn - dlg_page::dyn_id_base == id_custom_area_) - { - EnableWindow(ctrls_[ind], checked); - } - else if (sn - dlg_page::dyn_id_base == id_custom_gamma_) - { - EnableWindow(ctrls_[ind], checked); - } - } - } - done_ = true; - - return found; -} -const wchar_t* dlg_page::name(void) -{ - return name_.c_str(); -} -void dlg_page::set_view_size(SIZE size) -{ - int h = size.cy; - vsb_ = h < desired_size().cy; - if (!vsb_) - { - show_scroll_bar(SB_VERT, false); - } - else - { - size_view_.cy = h; - show_scroll_bar(SB_VERT, true); - SetScrollRange(hwnd(), SB_VERT, 0, desired_size().cy - h + dlg_page::sb_adden, FALSE); - } - - int w = size.cx; - hsb_ = w < desired_size().cx; - if (!hsb_) - { - show_scroll_bar(SB_HORZ, false); - } - else - { - size_view_.cx = w; - show_scroll_bar(SB_HORZ, true); - SetScrollRange(hwnd(), SB_HORZ, 0, desired_size().cx - w + dlg_page::sb_adden, FALSE); - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// diff --git a/sane/DlgPage.h b/sane/DlgPage.h deleted file mode 100644 index b836d37..0000000 --- a/sane/DlgPage.h +++ /dev/null @@ -1,228 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include "const_str.h" - -// CDlgIndicator 对话框 -#define FLOAT_FORMAT L"%.2f" -#define IS_STR_EQUAL(s1, s2) (wcscmp(s1, s2) == 0) -#define IS_EDIT(cls) IS_STR_EQUAL(cls, WC_EDITW) -#define IS_COMBOX(cls) IS_STR_EQUAL(cls, WC_COMBOBOXW) -#define IS_BUTTON(cls) IS_STR_EQUAL(cls, WC_BUTTONW) -#define IS_TRACKBAR(cls) IS_STR_EQUAL(cls, TRACKBAR_CLASSW) -#define IS_UPDOWN_ARROW(cls) IS_STR_EQUAL(cls, UPDOWN_CLASSW) - -#define RECT_W(r) (r.right - r.left) -#define RECT_H(r) (r.bottom - r.top) - -#define WM_SCAN_WORKING WM_USER + 301 // WPARAM: unused; LPARAM: unsed -#define WM_USB_PACKET_RECEIVED WM_USER + 302 -#define WM_IMAGE_RECEIVED WM_USER + 303 -#define WM_SCAN_FINISHED WM_USER + 304 // WPARAM: std::string* msg; LPARAM: boo err -#define WM_REFRESH_OPTION WM_USER + 311 // WPARAM: source option SN, LPARAM: unused now -#define WM_GET_CONFIG_OBJ WM_USER + 312 // WPARAM: bool*, [in]create new if NULL; [out]created, LPARAM: to receive the gb::sane_config_schm* object - - -extern HMODULE g_my_inst; -namespace gb -{ - class sane_config_schm; -} - -class dlg_base -{ - int modal_exit_; // set non-ZERO code to exit modal dialog - -protected: - HWND hwnd_; - HWND parent_; - UINT idd_; - bool abandon_hold_; - void(__stdcall* ui_event_notify_)(int uev, void* sender, void* param); - void* ui_notify_param_; - static std::wstring prop_name; - static BOOL CALLBACK dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); - - virtual BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp); - virtual void on_font_changed(void); - void create(void); - void notify_ui_event(int ev); - gb::sane_config_schm* get_config(bool* create); - -public: - dlg_base(HWND parent, UINT idd); - virtual ~dlg_base(); - - static void screen_2_client(HWND wnd, LPRECT r); - static void client_2_screen(HWND wnd, LPRECT r); - static bool get_max_size(SIZE& dst, const SIZE& src); // return whether changed dst - static bool get_max_size(SIZE& dst, int cx, int cy); // return whether changed dst - static int select_combo_text(HWND combo, const wchar_t* text); - static std::wstring get_wnd_text(HWND h); - static bool is_language_pack_default_code_page(void); - static std::wstring get_menu_text(HMENU menu, int ind); - static void center_window(HWND wnd, HWND parent); - - static int list_insert_column(HWND list_wnd, const wchar_t* text, int cx = 20, int ind = -1); - static int list_insert_item(HWND list_wnd, const wchar_t* text, int ind = -1); - static int list_get_item_count(HWND list_wnd); - static int list_get_column_count(HWND list_wnd); - static std::wstring list_get_text(HWND list_wnd, int ind, int sub = 0); - static void list_get_selected_items(HWND list_wnd, std::vector& sels); - static int list_set_item_text(HWND list_wnd, int item, int sub_item, const wchar_t* text); - -public: - void set_ui_event_notify(void(__stdcall* notify)(int, void*, void*), void* param); - HWND hwnd(void); - void show(bool visible, bool hold = false); - int do_modal(HWND parent); - void quit_modal(int non_zero_code); - void enable(bool enable); - void screen_2_client(LPRECT r); - void client_2_screen(LPRECT r); - HWND get_item(UINT id); - BOOL set_font(HFONT font); - HFONT get_font(void); - int get_string_width(const wchar_t* str, HWND wnd = NULL); - bool get_item_rect(UINT id, LPRECT r, bool client = true); - std::wstring get_item_text(UINT id); - int get_width_diff_as_text_length(UINT id); // - void offset_item(HWND wnd, int dx, int dy); - void offset_item(UINT id, int dx, int dy); - void expand_item(UINT id, int dx, int dy); - bool set_item_text(UINT id, const wchar_t* text); - int set_item_fit_to_text(UINT id); // return difference - void show_scroll_bar(int bar = SB_VERT, bool show = true); - bool track_mouse_hover(void); -}; - -class tooltip_wnd -{ - HWND hwnd_; - HWND parent_; - WNDPROC org_proc_; - - typedef struct _tip_ele - { - HWND ctrl; - RECT rect; - std::wstring tips; - - struct _tip_ele() - { - ctrl = NULL; - memset(&rect, 0, sizeof(rect)); - tips = L""; - } - bool operator==(const HWND& wnd) - { - return ctrl == wnd; - } - bool operator==(const RECT& r) - { - return memcmp(&rect, &r, sizeof(r)) == 0; - } - }TIPELEM; - std::vector elements_; - -public: - tooltip_wnd(); - ~tooltip_wnd(); - -public: - bool create(HWND parent); - void enable(bool enabled); - bool add_tool_tip_for_rect(const RECT& r, const wchar_t* tips); - bool add_tool_tip_for_ctrl(HWND ctrl, const wchar_t* tips); - bool remove_tool_tip_for_ctrl(HWND ctrl); -}; - -class dlg_page : public dlg_base -{ - std::wstring name_; - SIZE size_; - UINT ctrl_id_; - POINT pos_; - SANEAPI sane_; - SANE_Handle dev_; - bool done_; - std::vector ctrls_; - tooltip_wnd tips_wnd_; - - int id_dpi_; - float dpi_; - int id_paper_; - std::wstring paper_; - - int id_custom_area_; - int id_custom_left_; - int id_custom_right_; - int id_custom_top_; - int id_custom_bottom_; - int id_custom_gamma_; - - static std::wstring property_type; - static std::wstring property_host; - static std::wstring property_size; - static UINT dyn_id_base; - static int gap_x; - static int gap_y; - static int spin_w; - static int sb_adden; - - SIZE size_view_; - int vsb_pos_; - int hsb_pos_; - bool vsb_; - bool hsb_; - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void on_font_changed(void) override; - void align_second_control(bool ignore_single = false); // align the second control of a option controls - - HWND create_label(int sn, const wchar_t* title, int x, int y, SIZE size); - HWND create_slider(int sn, int x, int y, double lower, double upper, double step, double pos, LPSIZE size, bool is_double); - HWND create_edit(int sn, int x, int y, int h, int w = 50); - HWND create_combox(int sn, int x, int y, std::vector& vals, const wchar_t* cur_val, LPSIZE size); - HWND create_spin(int sn, HWND edit, double pos, double lower, double upper, bool is_double); - - HWND create_control_bool(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size); - HWND create_control_int(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size); - HWND create_control_float(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size); - HWND create_control_string(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size); - HWND create_control_button(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size); - - void handle_command(WORD code, WORD id, HANDLE ctrl); - BOOL on_notify(int ctrl_id, LPNMHDR pnmh); - - void* value_from_ctrl(HWND ctrl, SANE_Value_Type* type); // call free_ctrl_value to free the returned value, data according to SANE-standard - void set_ctrl_value(HWND ctrl, SANE_Value_Type type, void* val, bool only_me, bool skip_ctrl = false); - void free_ctrl_value(void* val); - int find_control_ind(HWND wnd); - void control_action(HWND wnd); - BOOL on_mouse_wheel(WORD vkey, short delta, short x, short y); - void on_vscroll(int pos, int sb_ev); - void on_hscroll(int pos, int sb_ev); - void on_mouse_hover(int x, int y, int flag); - -public: - dlg_page(HWND parent, const wchar_t* name, LPSANEAPI api, SANE_Handle dev); - ~dlg_page(); - -public: - bool add_control(int sn, const SANE_Option_Descriptor* desc, void* cur_val); - void add_control_done(void); - SIZE desired_size(void); - void show(void); - void hide(void); - bool refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val); - const wchar_t* name(void); - void set_view_size(SIZE size); -}; - - diff --git a/sane/DlgSaveScheme.cpp b/sane/DlgSaveScheme.cpp deleted file mode 100644 index 553031d..0000000 --- a/sane/DlgSaveScheme.cpp +++ /dev/null @@ -1,253 +0,0 @@ -// DlgSaveScheme.cpp: 实现文件 -// - -#include "DlgSaveScheme.h" -#include "resource.h" -#include "scanned_img.h" // for local_trans -#include "gb_json.h" -#include "mem_dc.h" - -#include "../../sdk/include/lang/app_language.h" - -#define WIDTH_MARGINS 10 - - - -dlg_save_scheme::dlg_save_scheme(HWND parent) : dlg_base(parent, IDD_SAVE_SCHEME) -{ - create(); - - std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_TITLE)); - int dif = 0; - RECT rc = { 0 }; - - SetWindowTextW(hwnd(), title.c_str()); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_DISCARD); - set_item_text(IDC_RADIO_DISCARD, title.c_str()); - set_item_fit_to_text(IDC_RADIO_DISCARD); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_OVERWRITE); - set_item_text(IDC_RADIO_OVERWRITE, title.c_str()); - dif = set_item_fit_to_text(IDC_RADIO_OVERWRITE); - - title = local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_NEW); - set_item_text(IDC_RADIO_NEW, title.c_str()); - dif = set_item_fit_to_text(IDC_RADIO_NEW); - offset_item(IDC_NAME, dif, 0); - GetWindowRect(get_item(IDC_NAME), &rc); - if(dif < RECT_W(rc) / 2) - expand_item(IDC_NAME, -dif, 0); - - { - RECT r = { 0 }, rc = { 0 }; - - GetWindowRect(hwnd(), &r); - GetWindowRect(get_item(IDC_NAME), &rc); - if (rc.right + WIDTH_MARGINS > r.right) - { - dif = rc.right + WIDTH_MARGINS - r.right; - r.right = rc.right + WIDTH_MARGINS; - MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE); - offset_item(IDOK, dif / 2, 0); - } - } - - title = local_trans::lang_trans_between_hz936(CONST_STRING_OK); - set_item_text(IDOK, title.c_str()); -} -dlg_save_scheme::~dlg_save_scheme() -{ -} - - -BOOL dlg_save_scheme::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - wchar_t text[40] = { 0 }; - BOOL ret = TRUE; - - switch (msg) - { - case WM_INITDIALOG: - on_init_dlg(); - UpdateWindow(hwnd()); - break; - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - case WM_NOTIFY: - handle_notify(wp, (LPNMHDR)lp); - break; - case WM_PAINT: - { - PAINTSTRUCT ps = { 0 }; - HDC hdc = BeginPaint(hwnd(), &ps); - { - compatible_dc dc(hdc); - on_paint(dc.get_dc()); - } - EndPaint(hwnd(), &ps); - } - break; - default: - ret = FALSE; - } - return ret; -} -void dlg_save_scheme::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - wchar_t cls[128] = { 0 }; - - GetClassNameW((HWND)ctrl, cls, _countof(cls) - 1); - if (IS_BUTTON(cls)) - { - if (code == BN_CLICKED) - { - EnableWindow(get_item(IDC_NAME), FALSE); - if (id == IDOK) - { - if (method_ == SAVE_NEW) - { - std::wstring text(get_wnd_text(get_item(IDC_NAME))); - - if (text.empty() || std::find(existing_.begin(), existing_.end(), text) != existing_.end()) - { - std::wstring info(L""), title(local_trans::lang_trans_between_hz936(CONST_STRING_ERROR)); - - if (text.empty()) - { - info = local_trans::lang_trans_between_hz936(CONST_STRING_REINPUT_SCHEME_NAME); - } - else - { - info = local_trans::lang_trans_between_hz936(CONST_STRING_LEFT_QUOTE) + text - + local_trans::lang_trans_between_hz936(CONST_STRING_RIGHT_QUOTE) - + local_trans::lang_trans_between_hz936(CONST_STRING_REINPUT_WHEN_EXISTING); - } - EnableWindow(get_item(IDC_NAME), TRUE); - MessageBoxW(hwnd(), info.c_str(), title.c_str(), MB_OK); - goto_name(); - return; - } - - name_ = std::move(text); - } - if (method_ == SAVE_DISCARD) - log_info((L"Discard changes on scheme '" + name_ + L"'.\r\n").c_str(), 0); - else - log_info((L"Save changes to scheme '" + name_ + L"'.\r\n").c_str(), 0); - quit_modal(id); - } - else if (id == IDC_RADIO_DISCARD) - method_ = SAVE_DISCARD; - else if (id == IDC_RADIO_OVERWRITE) - method_ = SAVE_OVERWRITE; - else if (id == IDC_RADIO_NEW) - { - method_ = SAVE_NEW; - EnableWindow(get_item(IDC_NAME), TRUE); - goto_name(); - } - } - } -} -void dlg_save_scheme::handle_notify(UINT id, LPNMHDR pnhdr) -{ -} -void dlg_save_scheme::layout(void) -{ -} - - -void dlg_save_scheme::on_init_dlg(void) -{ - check_radio(IDC_RADIO_DISCARD); -} -void dlg_save_scheme::on_paint(HDC hdc) -{ -} -void dlg_save_scheme::goto_name(void) -{ - SendMessageW(get_item(IDC_NAME), EM_SETSEL, 0, -1); - SetFocus(get_item(IDC_NAME)); -} -void dlg_save_scheme::check_radio(UINT id, bool check) -{ - SendMessage(get_item(id), BM_SETCHECK, check ? (WPARAM)BST_CHECKED : (WPARAM)BST_UNCHECKED, 0); -} - - -void dlg_save_scheme::set_info(const wchar_t* name, std::vector& existing, int mask, const wchar_t* new_name) -{ - bool set_method = false; - - name_ = name; - existing_ = existing; - set_item_text(IDC_NAME, new_name ? new_name : name); - - { - std::wstring schem(local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_OVERWRITE)); - schem += L" - '"; - schem += name; - schem += L"'"; - set_item_text(IDC_RADIO_OVERWRITE, schem.c_str()); - set_item_fit_to_text(IDC_RADIO_OVERWRITE); - - RECT r = { 0 }, rc = { 0 }; - - GetWindowRect(get_item(IDC_RADIO_OVERWRITE), &rc); - GetWindowRect(hwnd(), &r); - if (RECT_W(r) < RECT_W(rc) + WIDTH_MARGINS) - { - int diff = r.left + RECT_W(rc) + WIDTH_MARGINS - r.right; - r.right = r.left + RECT_W(rc) + WIDTH_MARGINS; - MoveWindow(hwnd(), r.left, r.top, RECT_W(r), RECT_H(r), FALSE); - offset_item(IDOK, diff / 2, 0); - } - } - - if (mask & SAVE_METHOD_MASK(SAVE_DISCARD)) - { - set_method = true; - method_ = SAVE_DISCARD; - EnableWindow(get_item(IDC_RADIO_DISCARD), TRUE); - check_radio(IDC_RADIO_DISCARD); - } - else - EnableWindow(get_item(IDC_RADIO_DISCARD), FALSE); - - if (mask & SAVE_METHOD_MASK(SAVE_OVERWRITE)) - { - if (!set_method) - { - set_method = true; - method_ = SAVE_OVERWRITE; - check_radio(IDC_RADIO_OVERWRITE); - } - EnableWindow(get_item(IDC_RADIO_OVERWRITE), TRUE); - } - else - EnableWindow(get_item(IDC_RADIO_OVERWRITE), FALSE); - - if (mask & SAVE_METHOD_MASK(SAVE_NEW)) - { - if (!set_method) - { - set_method = true; - method_ = SAVE_NEW; - check_radio(IDC_RADIO_NEW); - EnableWindow(get_item(IDC_NAME), TRUE); - } - EnableWindow(get_item(IDC_RADIO_NEW), TRUE); - } - else - EnableWindow(get_item(IDC_RADIO_NEW), FALSE); -} -save_method dlg_save_scheme::get_dispose(void) -{ - return method_; -} -std::wstring dlg_save_scheme::get_name(void) -{ - return name_; -} diff --git a/sane/DlgSaveScheme.h b/sane/DlgSaveScheme.h deleted file mode 100644 index e3a3129..0000000 --- a/sane/DlgSaveScheme.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#include -#include - -#include "DlgPage.h" - - -// CDlgSaveScheme 对话框 -enum save_method -{ - SAVE_DISCARD = 0, - SAVE_OVERWRITE, - SAVE_NEW, -}; -enum -{ - SAVE_REASON_QUIT_UI = 0, - SAVE_REASON_SWITCH_SCHEME, - SAVE_REASON_RESTORE, -}; -#define SAVE_METHOD_MASK(m) (1 << m) - -class dlg_save_scheme : public dlg_base -{ - std::vector existing_; - std::wstring name_ = L""; - save_method method_ = SAVE_DISCARD; - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void handle_command(WORD code, WORD id, HANDLE ctrl); - void handle_notify(UINT id, LPNMHDR pnhdr); - void layout(void); - - void on_init_dlg(void); - void on_paint(HDC hdc); - void goto_name(void); - void check_radio(UINT id, bool check = true); - -public: - dlg_save_scheme(HWND parent); - ~dlg_save_scheme(); - -public: - void set_info(const wchar_t* name, std::vector& existing, int mask, const wchar_t* new_name = nullptr); - save_method get_dispose(void); - std::wstring get_name(void); -}; diff --git a/sane/DlgSetting.cpp b/sane/DlgSetting.cpp deleted file mode 100644 index bd709fc..0000000 --- a/sane/DlgSetting.cpp +++ /dev/null @@ -1,752 +0,0 @@ -// DlgIndicator.cpp: 实现文件 -// - -#include "DlgSetting.h" -#include "resource.h" -#include "scanned_img.h" // for local_trans -#include "DlgPage.h" -#include "gb_json.h" - -#include "../../sdk/include/lang/app_language.h" - -// CDlgIndicator 对话框 -#include "DlgCfgMgr.h" -#include "DlgInput.h" -#include "DlgSaveScheme.h" - -#define MENU_CMD_0 ((unsigned short)0x8888) - -static IMPLEMENT_OPTION_STRING_COMPARE(cmp_sane_opt); - - -dlg_setting::dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name) : dlg_base(parent, IDD_SETTING) - , sane_api_(*api), sane_dev_(dev), with_scan_(with_scan) - , papers_(0), images_(0), err_(false), tab_(NULL), cfg_(NULL), cfg_file_(L""), twain_set_(nullptr), twain_schm_(nullptr) - , schm_from_empty_(false) -{ - std::wstring setting(local_trans::lang_trans_between_hz936(CONST_STRING_SETTING)); - - create(); - SetWindowTextW(hwnd(), (std::wstring(name) + L" " + setting).c_str()); - cfg_menu_ = CreatePopupMenu(); - InsertMenuW(cfg_menu_, 0, MF_BYPOSITION, MENU_CMD_0, local_trans::lang_trans_between_hz936(CONST_STRING_SAVE_CUR_CFG_AS).c_str()); - InsertMenuA(cfg_menu_, 1, MF_BYPOSITION | MF_SEPARATOR, MENU_CMD_0 + 1, ""); -} -dlg_setting::~dlg_setting() -{ - if (IsWindow(tab_)) - { - for (int i = 0; i < get_tab_count(); ++i) - { - TCITEMW item = { 0 }; - - item.mask = TCIF_PARAM; - TabCtrl_GetItem(tab_, i, &item); - if (item.lParam) - delete (dlg_page*)item.lParam; - } - DestroyWindow(tab_); - } - if (twain_schm_) - twain_schm_->release(); - - cfg_->save(local_trans::u2a(cfg_file_.c_str()).c_str()); - DestroyMenu(cfg_menu_); -} - -BOOL dlg_setting::handle_message(UINT msg, WPARAM wp, LPARAM lp) -{ - wchar_t text[40] = { 0 }; - BOOL ret = TRUE; - - switch (msg) - { - case WM_INITDIALOG: - on_init_dialog(); - break; - case WM_COMMAND: - handle_command(HIWORD(wp), LOWORD(wp), (HWND)lp); - break; - case WM_NOTIFY: - ret = on_notify((int)wp, (LPNMHDR)lp); - break; - case WM_REFRESH_OPTION: - refresh_controls((int)wp); - break; - case WM_GET_CONFIG_OBJ: - { - gb::sane_config_schm* schm = twain_schm_ ? twain_schm_ : cfg_->get_scheme(); - if (twain_schm_) - twain_schm_->add_ref(); - if (wp) - { - if (!schm && *(bool*)wp) - { - schm = cfg_->create_empty_scheme(true); - if (schm) - schm->begin_setting(); - schm_from_empty_ = true; - log_info(L"Create a new config scheme for recording user settings.\r\n", 0); - } - else - *(bool*)wp = false; - } - *((gb::sane_config_schm**)lp) = schm; - { - std::wstring name(schm ? local_trans::a2u(schm->get_scheme_name().c_str(), CP_UTF8) : L"default"); - name.insert(0, L"Return scheme '"); - name += L"' to user.\r\n"; - log_info(name.c_str(), 0); - } - } - break; - default: - ret = FALSE; - break; - } - - return ret; -} -void dlg_setting::handle_command(WORD code, WORD id, HANDLE ctrl) -{ - if (ctrl == NULL) - { - // menu command ... - if (id == MENU_CMD_0) - { - // save current scheme as ... - bool new_scheme = false; - gb::sane_config_schm* s = twain_schm_ ? twain_schm_ : cfg_->get_scheme(); - if (!s) - { - s = cfg_->copy_scheme(nullptr); - new_scheme = true; - } - - if (twain_schm_) - { - s->add_ref(); - twain_schm_->release(); - twain_schm_ = nullptr; - new_scheme = true; - } - - if (s) - { - std::vector all(get_stored_scheme_names()); - std::wstring cur(local_trans::a2u(s->get_scheme_name().c_str(), CP_UTF8)); - dlg_input dlg(hwnd(), cur.c_str()); - - dlg.set_no_repeats(all); - if (dlg.do_modal(hwnd()) == IDOK) - { - std::string name(local_trans::u2a(dlg.get_value().c_str(), CP_UTF8)); - gb::sane_config_schm* n = s; - if (new_scheme) - { - n->add_ref(); - n->end_setting(false); - } - else - { - n = s->copy(); - s->end_setting(true); - n->end_setting(false); - } - - if (cfg_->add_scheme(n, name.c_str())) - { - cfg_->select_scheme(name.c_str()); - n->begin_setting(); - } - n->release(); - } - s->release(); - } - } - else if(id > MENU_CMD_0 + 1) - { - // config scheme changed ... - std::string schm(local_trans::u2a(dlg_base::get_menu_text(cfg_menu_, id - MENU_CMD_0).c_str(), CP_UTF8)); - - log_info((L"Select scheme '" + local_trans::a2u(schm.c_str(), CP_UTF8) + L"' on scheme menu.\r\n").c_str(), 0); - - save_changes_to_cur_scheme(SAVE_REASON_SWITCH_SCHEME); - // if (cfg_->get_current_scheme_name() != schm) - { - gb::sane_config_schm* s = nullptr; - - if (cfg_->select_scheme(schm.c_str())) - { - s = cfg_->get_scheme(); - apply_scheme_(s, apply_param_); - if (s) - { - s->begin_setting(); - s->release(); - } - refresh_controls(-1); - // cfg_->save(); - } - } - } - } - else if (id == IDOK) - { - save_changes_to_cur_scheme(SAVE_REASON_QUIT_UI); - notify_over(); - } - else if (id == IDC_BUTTON_HELP) - { - SANE_Int after = 0; - SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_help_, SANE_ACTION_SET_VALUE, &after, &after); - } - else if (id == IDC_BUTTON_RESTORE) - { - log_info(L"Press 'Restore' button to restore settings\r\n", 0); - - save_changes_to_cur_scheme(SAVE_REASON_RESTORE); - - SANE_Int after = 0; - SANE_Status statu = sane_api_.sane_control_option_api(sane_dev_, id_restore_, SANE_ACTION_SET_VALUE, &after, &after); - refresh_controls(id_restore_); - cfg_->select_scheme(nullptr); - } - else if (id == IDC_BUTTON_SCAN) - { - // enable(false); - save_changes_to_cur_scheme(SAVE_REASON_QUIT_UI); - notify_ui_event(SANE_EVENT_UI_SCAN_COMMAND); - } - else if (id == IDC_BUTTON_CONFIG_MGR) - { - dlg_cfg_mgr dlg(cfg_, hwnd()); - gb::sane_config_schm* prev = cfg_->get_scheme(), * after = nullptr; - - dlg.do_modal(hwnd()); - after = cfg_->get_scheme(); - if (prev != after) // refresh settings and UI - { - { - std::wstring info(L"Current scheme has changed from '"); - if (prev) - info += local_trans::a2u(prev->get_scheme_name().c_str(), CP_UTF8) + L"' to '"; - else - info += L"default' to '"; - if (after) - info += local_trans::a2u(after->get_scheme_name().c_str(), CP_UTF8) + L"' in management UI\r\n"; - else - info += L"default' in management UI\r\n"; - log_info(info.c_str(), 0); - } - apply_scheme_(after, apply_param_); - refresh_controls(-1); - } - if (prev) - prev->release(); - if (after) - after->release(); - } - else if (id == IDC_BUTTON_CONFIG_MENU) - { - HMENU sub = cfg_menu_; // GetSubMenu(cfg_menu_, 0); - int ind = 2; // 0 - save as ...; 1 - separator - std::vector schemes; - - while (DeleteMenu(sub, 2, MF_BYPOSITION)); - cfg_->get_all_schemes(schemes); - for (auto& v : schemes) - { - UINT flag = MF_BYPOSITION; - - if (twain_set_ && *twain_set_ == false && v == cfg_->get_current_scheme_name()) - flag |= MF_CHECKED; - InsertMenuW(sub, ind, flag, MENU_CMD_0 + ind, local_trans::a2u(v.c_str(), CP_UTF8).c_str()); - ind++; - } - - RECT r = { 0 }; - GetWindowRect(get_item(IDC_BUTTON_CONFIG_MENU), &r); - TrackPopupMenu(cfg_menu_, TPM_LEFTALIGN | TPM_BOTTOMALIGN, r.left, r.top, 0, hwnd(), NULL); - } -} -void dlg_setting::notify_over(void) -{ - notify_ui_event(SANE_EVENT_UI_CLOSE_SETTING); -} -void dlg_setting::on_init_dialog(void) -{ - dlg_page* page = NULL; - SANE_Int sn = 1; - SIZE size = { 0 }; - RECT r = { 0 }, rme = { 0 }; - int y = 0; - const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++); - - while (desc) - { - if (desc->type == SANE_TYPE_GROUP) - { - if (page) - { - page->add_control_done(); - dlg_base::get_max_size(size, page->desired_size()); - } - page = add_tab(desc->title); - } - else if (page) - { - char* buf = new char[desc->size + 4]; - SANE_Int info = 0; - - memset(buf, 0, desc->size + 4); - sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info); - page->add_control(sn - 1, desc, buf); - delete[] buf; - } - else if(desc->type == SANE_TYPE_BUTTON) - { - if (strcmp(SANE_STD_OPT_NAME_HELP, desc->name) == 0) - { - ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_HELP), SW_SHOW); - id_help_ = sn - 1; - } - else if (strcmp(SANE_STD_OPT_NAME_RESTORE, desc->name) == 0) - { - ShowWindow(GetDlgItem(hwnd_, IDC_BUTTON_RESTORE), SW_SHOW); - id_restore_ = sn - 1; - } - } - desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++); - } - if (page) - { - page->add_control_done(); - dlg_base::get_max_size(size, page->desired_size()); - } - - if (size.cx || size.cy || IsWindow(tab_)) - { - // resize ... - GetClientRect(hwnd(), &rme); - if (size.cx < rme.right - rme.left) - size.cx = rme.right - rme.left; - - if (IsWindow(tab_)) - { - GetWindowRect(tab_, &r); - y = r.bottom - r.top; - size.cy += y; - r.right = r.left + size.cx; - screen_2_client(&r); - MoveWindow(tab_, r.left, r.top, r.right - r.left, y, TRUE); - } - - RECT desk = { 0 }; - int diff = 0; - - GetClientRect(GetDesktopWindow(), &desk); - GetWindowRect(hwnd(), &r); - r.right += size.cx - (rme.right - rme.left); - r.bottom += size.cy; - if (r.bottom - r.top > desk.bottom - desk.top) - { - diff = (r.bottom - r.top) - (desk.bottom - desk.top) + 100; - r.top = desk.top; - r.bottom = desk.bottom - 100; - } - MoveWindow(hwnd(), r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE); - - size.cy -= diff; - for (int i = 0; page = get_page(i); ++i) - { - MoveWindow(page->hwnd(), 0, y, size.cx, size.cy - y, TRUE); - page->set_view_size(size); - } - - offset_item(IDC_BUTTON_SCAN, 0, size.cy); - offset_item(IDC_BUTTON_CONFIG_MGR, size.cx - RECT_W(rme), size.cy); - offset_item(IDC_BUTTON_CONFIG_MENU, size.cx - RECT_W(rme), size.cy); - offset_item(IDC_BUTTON_HELP, size.cx - RECT_W(rme), size.cy); - offset_item(IDC_BUTTON_RESTORE, size.cx - RECT_W(rme), size.cy); - offset_item(IDOK, size.cx - RECT_W(rme), size.cy); - - ShowWindow(get_item(IDC_BUTTON_CONFIG_MGR), SW_SHOW); - ShowWindow(get_item(IDC_BUTTON_CONFIG_MENU), SW_SHOW); - } - if (with_scan_) - ShowWindow(get_item(IDC_BUTTON_SCAN), SW_SHOW); - - if (!dlg_base::is_language_pack_default_code_page()) - { - std::wstring title(local_trans::lang_trans_between_hz936(CONST_STRING_CFG_MANAGER)); - - ::SetDlgItemTextW(hwnd(), IDC_BUTTON_CONFIG_MGR, title.c_str()); - y = set_item_fit_to_text(IDC_BUTTON_CONFIG_MGR); - if (y) - offset_item(IDC_BUTTON_CONFIG_MGR, -y, 0); - - ::SetDlgItemTextW(hwnd(), IDC_BUTTON_SCAN, local_trans::lang_trans_between_hz936(CONST_STRING_SCAN).c_str()); - ::SetDlgItemTextW(hwnd(), IDC_BUTTON_RESTORE, local_trans::lang_trans_between_hz936(CONST_STRING_RESTORE).c_str()); - ::SetDlgItemTextW(hwnd(), IDC_BUTTON_HELP, local_trans::lang_trans_between_hz936(CONST_STRING_HELP).c_str()); - ::SetDlgItemTextW(hwnd(), IDOK, local_trans::lang_trans_between_hz936(CONST_STRING_OK).c_str()); - } - - select_page(0); - UpdateWindow(hwnd()); -} -BOOL dlg_setting::on_notify(int ctrl_id, LPNMHDR pnmh) -{ - BOOL ret = TRUE; - - if (pnmh->hwndFrom == tab_) - { - if (pnmh->code == TCN_SELCHANGING) - ret = FALSE; - else if (pnmh->code == TCN_SELCHANGE) - select_page(TabCtrl_GetCurSel(tab_)); - } - - return ret; -} -int dlg_setting::get_tab_count(void) -{ - int count = 0; - - if (IsWindow(tab_)) - count = TabCtrl_GetItemCount(tab_); - - return count; -} -dlg_page* dlg_setting::add_tab(const char* utf8_title) -{ - std::wstring title(local_trans::a2u(utf8_title, CP_UTF8)); - dlg_page *page = new dlg_page(hwnd(), title.c_str(), &sane_api_, sane_dev_); - HFONT font = (HFONT)SendMessage(get_item(IDOK), WM_GETFONT, 0, 0); - LOGFONTW lf = { 0 }; - - GetObjectW(font, sizeof(lf), &lf); - page->set_font(font); - if (!IsWindow(tab_)) - { - HDC hdc = GetWindowDC(hwnd()); - SIZE text = { 0 }; - - GetTextExtentPointW(hdc, title.c_str(), title.length(), &text); - ReleaseDC(hwnd(), hdc); - tab_ = CreateWindowW(L"SysTabControl32", L"pages", WS_CHILD | WS_VISIBLE, 0, 0, 100, text.cy + 6, hwnd(), NULL, g_my_inst, NULL); - SendMessage(tab_, WM_SETFONT, (WPARAM)SendMessage(get_item(IDOK), WM_GETFONT, 0, 0), 1); - SetWindowLong(tab_, GWL_ID, 1234); - ShowWindow(tab_, SW_SHOW); - } - - TC_ITEMW item = { 0 }; - - item.mask = TCIF_PARAM | TCIF_TEXT; - item.lParam = (LPARAM)page; - item.pszText = &title[0]; - TabCtrl_InsertItem(tab_, get_tab_count(), &item); - page->hide(); - - return page; -} -dlg_page* dlg_setting::get_page(int index) -{ - dlg_page* page = NULL; - - if (IsWindow(tab_) && index >= 0 && index < get_tab_count()) - { - TCITEMW item = { 0 }; - - item.mask = TCIF_PARAM; - TabCtrl_GetItem(tab_, index, &item); - page = (dlg_page*)item.lParam; - } - - return page; -} -dlg_page* dlg_setting::get_page(const char* utf8_title) -{ - dlg_page* page = NULL; - std::wstring unic(local_trans::a2u(utf8_title, CP_UTF8)); - - for (int i = 0; i < get_tab_count(); ++i) - { - TCITEMW item = { 0 }; - wchar_t buf[80] = { 0 }; - - item.mask = TCIF_TEXT | TCIF_PARAM; - item.pszText = buf; - item.cchTextMax = _countof(buf) - 1; - TabCtrl_GetItem(tab_, i, &item); - if (unic == buf) - { - page = (dlg_page*)item.lParam; - break; - } - } - - return page; -} -dlg_page* dlg_setting::select_page(int index) -{ - dlg_page* ret = NULL, *cur = NULL; - - for (int i = 0; cur = get_page(i); ++i) - { - if (i == index) - { - ret = cur; - cur->show(); - } - else - cur->hide(); - } - - return ret; -} -void dlg_setting::refresh_controls(int src_sn) -{ - int sn = 1; - const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++); - - while (desc) - { - char* buf = new char[desc->size + 8]; - SANE_Int info = 0; - dlg_page* page = NULL; - memset(buf, 0, desc->size + 8); - sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info); - for (int i = 0; page = get_page(i); ++i) - { - if (page->refresh(sn - 1, desc, buf)) - break; - } - delete[] buf; - desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++); - } -} -void dlg_setting::save_changes_to_cur_scheme(int reason) -{ - // discard, overwrite, new - int items = 0; - bool changed = false; - std::vector now(get_stored_scheme_names()); - - if (!cfg_) - return; - - if (twain_set_ && reason != SAVE_REASON_QUIT_UI) - *twain_set_ = false; - - if (twain_schm_) - { - changed = twain_schm_->has_changed(&items); - if (changed) - { - dlg_save_scheme dlg(hwnd()); - std::wstring sug(L""); - - sug = local_trans::a2u(twain_schm_->auto_gen_scheme_name(local_trans::lang_trans_between_hz936, nullptr, false).c_str(), CP_UTF8); - dlg.set_info(local_trans::a2u(twain_schm_->get_scheme_name().c_str(), CP_UTF8).c_str(), now - , SAVE_METHOD_MASK(SAVE_DISCARD) | SAVE_METHOD_MASK(SAVE_NEW), - sug.c_str()); - dlg.do_modal(hwnd()); - if(dlg.get_dispose() == SAVE_NEW) - { - std::string name(local_trans::u2a(dlg.get_name().c_str(), CP_UTF8)); - if (cfg_->add_scheme(twain_schm_, name.c_str()) && - reason == SAVE_REASON_QUIT_UI) - { - cfg_->select_scheme(name.c_str()); - if (twain_set_) - *twain_set_ = false; - } - } - } - twain_schm_->release(); - twain_schm_ = nullptr; - } - else - { - gb::sane_config_schm* schm = cfg_->get_scheme(); - if (schm) - { - changed = schm->has_changed(&items); - if (changed) - { - if (schm_from_empty_) - schm->end_setting(false); - else - { - dlg_save_scheme dlg(hwnd()); - std::wstring name(local_trans::a2u(schm->get_scheme_name().c_str(), CP_UTF8)), - suggest(local_trans::a2u(schm->auto_gen_scheme_name(local_trans::lang_trans_between_hz936, nullptr, false).c_str(), CP_UTF8)); - - dlg.set_info(name.c_str(), now, SAVE_METHOD_MASK(SAVE_DISCARD) | SAVE_METHOD_MASK(SAVE_OVERWRITE) | SAVE_METHOD_MASK(SAVE_NEW) - , suggest.c_str()); - dlg.do_modal(hwnd()); - - int dispose = dlg.get_dispose(); - if (dispose == SAVE_NEW) - { - std::string uname(local_trans::u2a(dlg.get_name().c_str(), CP_UTF8)); - gb::sane_config_schm* s = schm->copy(); - - schm->end_setting(true); - s->end_setting(false); - cfg_->add_scheme(s, uname.c_str()); - s->release(); - if (reason == SAVE_REASON_QUIT_UI) - cfg_->select_scheme(uname.c_str()); - } - else - { - schm->end_setting(dispose == SAVE_DISCARD); - if (dispose == SAVE_DISCARD && reason == SAVE_REASON_QUIT_UI && twain_set_) - { - std::wstring info(local_trans::a2u(schm->get_scheme_name().c_str(), CP_UTF8)); - - info.insert(0, L"User discard the changes on scheme '"); - info += L"' and will quit UI, set temporary scheme flag!\r\n"; - log_info(info.c_str(), 0); - - *twain_set_ = true; - } - } - } - } - schm->release(); - } - } - schm_from_empty_ = false; -} - -void dlg_setting::set_config(gb::scanner_cfg* cfg, const wchar_t* file, void(__stdcall* apply)(gb::sane_config_schm*, void*), void* param, bool* twain_set) -{ - cfg_ = cfg; - cfg_file_ = file; - apply_scheme_ = apply; - apply_param_ = param; - twain_set_ = twain_set; - - if (twain_set && *twain_set && cfg_) - { - // create a temporary scheme because of APP has changed the setting after we applied the store scheme ... - twain_schm_ = new gb::sane_config_schm(cfg_); - - int sn = 1; - const SANE_Option_Descriptor* desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++); - - while (desc) - { - if (desc->type != SANE_TYPE_BUTTON && desc->type != SANE_TYPE_GROUP) - { - char* buf = new char[desc->size + 8]; - SANE_Int info = 0; - dlg_page* page = NULL; - memset(buf, 0, desc->size + 8); - sane_api_.sane_control_option_api(sane_dev_, sn - 1, SANE_ACTION_GET_VALUE, buf, &info); - if (desc->type == SANE_TYPE_STRING) - { - std::string defl(to_default_language(buf, nullptr)); - twain_schm_->config_changed(sn - 1, defl.c_str(), defl.length()); - } - else - { - int len = desc->size; - switch (desc->type) - { - case SANE_TYPE_BOOL: - len = sizeof(SANE_Bool); - break; - case SANE_TYPE_INT: - len = sizeof(SANE_Int); - break; - case SANE_TYPE_FIXED: - len = sizeof(SANE_Fixed); - break; - } - twain_schm_->config_changed(sn - 1, buf, len); - } - - delete[] buf; - } - desc = sane_api_.sane_get_option_descriptor_api(sane_dev_, sn++); - } - twain_schm_->has_changed(&sn); - twain_schm_->auto_gen_scheme_name(local_trans::lang_trans_between_hz936, nullptr); - twain_schm_->begin_setting(); - if(sn) - { - std::wstring name(local_trans::a2u(cfg_->get_current_scheme_name().c_str(), CP_UTF8)); - name.insert(0, L"TWAIN-app has changed " + std::to_wstring(sn) + L" setting(s) after we applied stored scheme '"); - name += L"'\r\n"; - log_info(name.c_str(), 0); - } - } - else if(cfg_) - { - gb::sane_config_schm* schm = cfg_->get_scheme(); - if (schm) - { - schm->begin_setting(); - schm->release(); - } - } -} -HWND dlg_setting::window(void) -{ - return hwnd_; -} -HWND dlg_setting::parent(void) -{ - return parent_; -} -//void dlg_setting::show(void) -//{ -// RECT rp, r, desk; -// -// if (IsWindow(parent_)) -// GetWindowRect(parent_, &rp); -// else -// GetWindowRect(GetDesktopWindow(), &rp); -// GetWindowRect(hwnd_, &r); -// GetWindowRect(GetDesktopWindow(), &desk); -// -// rp.left += (rp.right - rp.left - (r.right - r.left)) / 2; -// rp.top += (rp.bottom - rp.top - (r.bottom - r.top)) / 2; -// if (rp.top > desk.bottom) -// rp.top = desk.bottom - (r.bottom - r.top); -// if (rp.top < desk.top) -// rp.top = desk.top; -// if (rp.left > desk.right) -// rp.left = desk.right - (rp.right - rp.left); -// if (rp.left < desk.left) -// rp.left = desk.left; -// SetWindowPos(hwnd_, HWND_TOPMOST, rp.left, rp.top, r.right - r.left, r.bottom - r.top, SWP_NOSIZE | SWP_SHOWWINDOW); -// UpdateWindow(hwnd_); -//} -void dlg_setting::hide(void) -{ - ShowWindow(hwnd_, SW_HIDE); -} -void dlg_setting::notify_scan_over(void) -{ - enable(true); -} -std::vector dlg_setting::get_stored_scheme_names(void) -{ - std::vector now; - std::vector wnow; - - if (cfg_) - { - cfg_->get_all_schemes(now); - for (auto& v : now) - wnow.push_back(local_trans::a2u(v.c_str(), CP_UTF8)); - } - - return std::move(wnow); -} -// CDlgIndicator 消息处理程序 diff --git a/sane/DlgSetting.h b/sane/DlgSetting.h deleted file mode 100644 index 612e459..0000000 --- a/sane/DlgSetting.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "DlgPage.h" - -// CDlgIndicator 对话框 -//#define USE_SOLE_WIN_THREAD - -#ifdef USE_SOLE_WIN_THREAD -#include -#include -#endif - -namespace gb -{ - class scanner_cfg; -} -class dlg_setting : public dlg_base -{ - SANEAPI sane_api_; - SANE_Handle sane_dev_; - bool with_scan_; - unsigned int papers_; - unsigned int images_; - bool err_; - int id_help_; - int id_restore_; - gb::scanner_cfg *cfg_; - std::wstring cfg_file_; - bool *twain_set_; - gb::sane_config_schm* twain_schm_; - bool schm_from_empty_; - - HMENU cfg_menu_; - void(__stdcall* apply_scheme_)(gb::sane_config_schm*, void*); - void* apply_param_; - - HWND tab_; - -#ifdef USE_SOLE_WIN_THREAD - std::unique_ptr thread_; -#endif - - BOOL handle_message(UINT msg, WPARAM wp, LPARAM lp) override; - void handle_command(WORD code, WORD id, HANDLE ctrl); - void notify_over(void); - void on_init_dialog(void); - BOOL on_notify(int ctrl_id, LPNMHDR pnmh); - int get_tab_count(void); - dlg_page* add_tab(const char* utf8_title); - dlg_page* get_page(int index); - dlg_page* get_page(const char* utf8_title); - dlg_page* select_page(int index); - void refresh_controls(int src_sn); - void save_changes_to_cur_scheme(int reason); - -public: - dlg_setting(HWND parent, LPSANEAPI api, SANE_Handle dev, bool with_scan, const wchar_t* name); - ~dlg_setting(); - -public: - void set_config(gb::scanner_cfg* cfg, const wchar_t* file, void(__stdcall* apply)(gb::sane_config_schm*, void*), void* param, bool* twain_set = nullptr); - HWND window(void); - HWND parent(void); - //void show(void); - void hide(void); - void notify_scan_over(void); - std::vector get_stored_scheme_names(void); -}; diff --git a/sane/const_str.h b/sane/const_str.h deleted file mode 100644 index c52c879..0000000 --- a/sane/const_str.h +++ /dev/null @@ -1,94 +0,0 @@ -// For: const string list -// -// Date: 2023-02-07 -// -// Format: all strings are defined in unicode -// - -#pragma once - -#define CONST_STRING_CUSTOM_AREA L"\u81EA\u5B9A\u4E49\u626B\u63CF\u533A\u57DF" -#define CONST_STRING_UNIT L"\u5355\u4F4D" -#define CONST_STRING_UNIT_MM L"\u6BEB\u7C73" -#define CONST_STRING_UNIT_INCH L"\u82F1\u5BF8" -#define CONST_STRING_UNIT_PIXEL L"\u50CF\u7D20" -#define CONST_STRING_AREA_SET L"\u533A\u57DF\u8BBE\u7F6E" -#define CONST_STRING_LEFT L"\u5DE6" -#define CONST_STRING_TOP L"\u4E0A" -#define CONST_STRING_WIDTH L"\u5BBD" -#define CONST_STRING_HEIGHT L"\u9AD8" -#define CONST_STRING_RESTORE_AREA L"\u6062\u590D\u533A\u57DF" -#define CONST_STRING_OK L"\u786E\u5B9A" -#define CONST_STRING_CANCEL L"\u53D6\u6D88" -#define CONST_STRING_MULTIPLE L"\u00d7" -#define CONST_STRING_OPT_PAPER L"\u7EB8\u5F20\u5C3A\u5BF8" - -#define CONST_STRING_CFG_MANAGER L"\u914D\u7F6E\u7BA1\u7406" -#define CONST_STRING_CFG_SCHEME L"\u914D\u7F6E\u65B9\u6848" -#define CONST_STRING_DEL_SELECTED L"\u5220\u9664\u9009\u4E2D\u9879" -#define CONST_STRING_DEL_ALL L"\u5168\u90E8\u5220\u9664" -#define CONST_STRING_CFG_CONTENT L"\u914D\u7F6E\u5185\u5BB9" -#define CONST_STRING_CFG_NAME L"\u914D\u7F6E\u540D\u79F0" - -#define CONST_STRING_CUSTOM_TONE L"\u81EA\u5B9A\u4E49\u8272\u8C03\u66F2\u7EBF" -#define CONST_STRING_TONE_SCHEME L"\u8272\u8C03\u65B9\u6848" -#define CONST_STRING_COLOR_CHANNEL L"\u989C\u8272\u901A\u9053" -#define CONST_STRING_INITIALIZE L"\u521D\u59CB\u5316" -#define CONST_STRING_INPUT L"\u8F93\u5165" -#define CONST_STRING_OUTPUT L"\u8F93\u51FA" -#define CONST_STRING_CUSTOM L"\u81EA\u5B9A\u4E49" -#define CONST_STRING_NEG_PHOTO L"\u8d1f\u7247" -#define CONST_STRING_COLOR_NEG_PHOTO L"\u5f69\u8272\u8d1f\u7247" -#define CONST_STRING_DARKER L"\u8f83\u6697" -#define CONST_STRING_BRIGHTER L"\u8f83\u4eae" -#define CONST_STRING_RED L"\u7ea2" -#define CONST_STRING_GREEN L"\u7eff" -#define CONST_STRING_BLUE L"\u84dd" -#define CONST_STRING_GRAY L"\u7070" - -#define CONST_STRING_SCANNING L"\u6B63\u5728\u626B\u63CF\u2026\u2026" -#define CONST_STRING_PAPER L"\u7EB8\u5F20" -#define CONST_STRING_IMAGE L"\u56FE\u7247" -#define CONST_STRING_TOTAL_SCANNED L"\u603b\u8ba1\u626b\u63cf\u56fe\u7247" -#define CONST_STRING_CLOSE L"\u5173\u95ed" -#define CONST_STRING_SCAN_OVER L"\u626b\u63cf\u7ed3\u675f" - -#define CONST_STRING_CHOOSE_DEVICE L"\u8BF7\u9009\u62E9\u8BBE\u5907" -#define CONST_STRING_DEVICE_NAME L"\u8BBE\u5907\u540D\u79F0" -#define CONST_STRING_SERIAL_NUM L"\u5E8F\u5217\u53F7" - -#define CONST_STRING_INPUT_VAL L"\u8BF7\u8F93\u5165\u65B0\u503C" -#define CONST_STRING_RE_INPUT L"\u8BF7\u91CD\u65B0\u8F93\u5165" -#define CONST_STRING_NO_INPUT L"\u6CA1\u6709\u8F93\u5165\u5185\u5BB9" -#define CONST_STRING_ALREADY_EXISTS L"\u5DF2\u7ECF\u5B58\u5728" - -#define CONST_STRING_NOT_SUPPORT_SET L"\u6B64\u8BBE\u5907\u4E0D\u652F\u6301\u5C06" -#define CONST_STRING_SET_TO_BE L"\u8BBE\u7F6E\u4E3A" -#define CONST_STRING_PARAMETER_ERROR L"\u53C2\u6570\u9519\u8BEF" -#define CONST_STRING_PARAMETER_ORIGIN L"\u539F\u53C2\u6570" -#define CONST_STRING_PARAMETER_INEXACT L"\u4E0D\u7CBE\u786E\u6216\u8BBE\u5907\u4E0D\u652F\u6301\uFF0C\u5DF2\u8C03\u6574\u4E3A" -#define CONST_STRING_PARAMETER_ADJUSTED L"\u53C2\u6570\u8C03\u6574" -#define CONST_STRING_SET_AREA L"\u8bbe\u7f6e\u533a\u57df" -#define CONST_STRING_SET_TONE L"\u8bbe\u7f6e\u8272\u8c03\u66f2\u7ebf" - -#define CONST_STRING_SETTING L"\u8BBE\u7F6E" -#define CONST_STRING_SAVE_CUR_CFG_AS L"\u5F53\u524D\u914D\u7F6E\u53E6\u5B58\u4E3A" -#define CONST_STRING_SCAN L"\u626B\u63CF" -#define CONST_STRING_RESTORE L"\u6062\u590D\u9ED8\u8BA4\u503C" -#define CONST_STRING_HELP L"\u5E2E\u52A9" - - - -#define CONST_STRING_OPEN_FAILED L"\u6253\u5F00\u5931\u8D25" -#define CONST_STRING_START_FAILED L"\u542F\u52A8\u5931\u8D25" -#define CONST_STRING_ERROR L"\u9519\u8BEF" - - -#define CONST_STRING_SAVE_TITLE L"\u5F53\u524D\u914D\u7F6E\u5DF2\u7ECF\u66F4\u6539\uFF0C\u8BF7\u9009\u62E9\u4FDD\u5B58\u65B9\u5F0F" -#define CONST_STRING_SAVE_DISCARD L"\u4E0D\u4FDD\u5B58\uFF0C\u4EC5\u7528\u4E8E\u8BE5\u6B21\u626B\u63CF\u6216\u653E\u5F03\u66F4\u6539" -#define CONST_STRING_SAVE_OVERWRITE L"\u8986\u76D6\u73B0\u6709\u65B9\u6848" -#define CONST_STRING_SAVE_NEW L"\u4FDD\u5B58\u4E3A\u65B0\u65B9\u6848" -#define CONST_STRING_REINPUT_SCHEME_NAME L"\u8BF7\u8F93\u5165\u65B0\u914D\u7F6E\u65B9\u6848\u540D\u79F0\u3002" -#define CONST_STRING_LEFT_QUOTE L"\u201C" -#define CONST_STRING_RIGHT_QUOTE L"\u201D" -#define CONST_STRING_REINPUT_WHEN_EXISTING L"\u5DF2\u7ECF\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u8F93\u5165\u3002" \ No newline at end of file diff --git a/sane/gb_json.cpp b/sane/gb_json.cpp deleted file mode 100644 index 967b387..0000000 --- a/sane/gb_json.cpp +++ /dev/null @@ -1,2038 +0,0 @@ - -#include "gb_json.h" -#include -#include - -#include "../../sdk/include/huagao/brand.h" -#include "../../sdk/include/sane/sane_ex.h" - -#if defined(WIN32) || defined(_WIN64) -#define bzero(b, s) memset(b, 0, s) -#endif - - -namespace special_char_trans -{ - struct - { - const char* writedown_text; - char readable_char; - }transferred_chars[] = { { "\\\"", '\"' } - , { "\\'", '\'' } - , { "\\a", '\a' } - , { "\\b", '\b' } - , { "\\f", '\f' } - , { "\\n", '\n' } - , { "\\r", '\r' } - , { "\\t", '\t' } - , { "\\v", '\v' } - // , { "\\?", '\?' } - , { "\\\\", '\\' } - , { "\\/", '/' } - // , { "\\0", '\0' } - }; - - void to_writedown(std::string& str) - { - std::string trans(str); - const char* ptr = trans.c_str(); - - str.clear(); - while (*ptr) - { - bool rep = false; - if (*ptr == '\\') - { - if (ptr[1] == '\\') - { - str += "\\\\"; - ptr++; - rep = true; - } - else if (ptr[1] == '/' || - ptr[1] == 'a' || - ptr[1] == 'b' || - ptr[1] == 'f' || - ptr[1] == 'n' || - ptr[1] == 'r' || - ptr[1] == 't' || - ptr[1] == 'u' || - ptr[1] == 'v') - { - str += "\\"; - ptr++; - } - else - { - str += "\\\\"; - rep = true; - } - } - else - { - for (size_t i = 0; i < sizeof(transferred_chars) / sizeof(transferred_chars[0]); ++i) - { - if (*ptr == transferred_chars[i].readable_char) - { - str += transferred_chars[i].writedown_text; - rep = true; - break; - } - } - } - if (!rep) - str.append(1, *ptr); - ptr++; - } - } -} - -namespace gb -{ - static std::vector split_with(const char* str, const char* splitor = "/") - { - std::vector ret; - std::string src(str); - size_t pos = src.find(splitor); - - while(pos != std::string::npos) - { - if(pos++) - ret.push_back(src.substr(0, pos - 1)); - src.erase(0, pos + strlen(splitor)); - pos = src.find(splitor); - } - if(src.length()) - ret.push_back(src); - - return ret; - } - static int load_mini_file(const char* file, std::string& cont) - { - FILE* src = fopen(file, "rb"); - if (src) - { - size_t size = 0; - char *buf = NULL; - - fseek(src, 0, SEEK_END); - size = ftell(src); - fseek(src, 0, SEEK_SET); - buf = new char[size + 4]; - memset(buf, 0, size + 4); - fread(buf, 1, size, src); - fclose(src); - cont = std::string(buf, size); - delete[] buf; - - return 0; - } - else - return errno; - } - - refer::refer() : ref_(1) - {} - refer::~refer() - {} - - long refer::add_ref(void) - { -#if defined(WIN32) || defined(_WIN64) - return InterlockedIncrement(&ref_); -#else - return ++ref_; -#endif - } - long refer::release(void) - { -#if defined(WIN32) || defined(_WIN64) - long ref = InterlockedDecrement(&ref_); -#else - long ref = --ref_; -#endif - - if (ref == 0) - delete this; - - return ref; - } - - - json::json(char* json_txt) : type_(VAL_TYPE_OBJECT), key_(""), strval_(""), cur_child_(-1) - { - simple_val_.dval = .0f; - if (json_txt) - attach_text(json_txt); - } - json::json(const char* key, bool val) : type_(VAL_TYPE_BOOL), key_(key ? key : ""), strval_(""), cur_child_(-1) - { - simple_val_.bval = val; - } - json::json(const char* key, int val) : type_(VAL_TYPE_INT), key_(key ? key : ""), strval_(""), cur_child_(-1) - { - simple_val_.nval = val; - } - json::json(const char* key, double val) : type_(VAL_TYPE_FLOAT), key_(key ? key : ""), strval_(""), cur_child_(-1) - { - simple_val_.dval = val; - } - json::json(const char* key, const char* val) : type_(VAL_TYPE_STRING), key_(key ? key : ""), strval_(val ? val : ""), cur_child_(-1) - {} - json::json(json& r) - { - copy_from(r); - } - json::~json() - { - clear(); - } - - std::string json::object_key(json* jsn) - { - return "\"" + jsn->key() + "\":"; - } - std::string json::array_key(json* jsn) - { - return ""; - } - - void json::from_cjson(cJSON* cj) - { - key_ = cj && cj->string ? cj->string : ""; - while (cj) - { - json* child = nullptr; - if (cj->type == cJSON_True) - { - child = new json(cj->string, true); - } - else if (cj->type == cJSON_False) - { - child = new json(cj->string, false); - } - else if (cj->type == cJSON_Number) - { - if (cj->valuedouble - (int)cj->valuedouble < .00001) - { - child = new json(cj->string, cj->valueint); - } - else - { - child = new json(cj->string, cj->valuedouble); - } - } - else if (cj->type == cJSON_String) - { - child = new json(cj->string, cj->valuestring); - } - else if (cj->type == cJSON_Object || cj->type == cJSON_Array) - { - child = new json(); - child->from_cjson(cj->child); - child->key_ = cj->string ? cj->string : ""; - } - arr_val_.push_back(child); - cj = cj->next; - } - - //if (arr_val_.size() == 1 && arr_val_[0]->arr_val_.size() == 0) - //{ - // json* child = arr_val_[0]; - // - // if (!child->key_.empty()) // array - // { - // arr_val_.clear(); - // type_ = child->type_; - // key_ = child->key_; - // simple_val_.dval = child->simple_val_.dval; - // strval_ = child->strval_; - // for (auto& v : child->arr_val_) - // arr_val_.push_back(v); - // child->arr_val_.clear(); - // child->release(); - // } - //} - - if (arr_val_.size()) - { - type_ = arr_val_[0]->key().empty() ? VAL_TYPE_ARRAY : VAL_TYPE_OBJECT; - } - } - json* json::find_child(const char* key, bool remove) - { - json* ret = nullptr; - - if (type_ == VAL_TYPE_OBJECT) - { - for (size_t i = 0; i < arr_val_.size(); ++i) - { - if (arr_val_[i]->key() == key) - { - ret = arr_val_[i]; - if (remove) - arr_val_.erase(arr_val_.begin() + i); - else - ret->add_ref(); - - break; - } - } - } - - return ret; - } - - void json::copy_from(json& r) - { - clear(); - - type_ = r.type_; - key_ = r.key_; - simple_val_.dval = r.simple_val_.dval; - strval_ = r.strval_; - for (auto& v : r.arr_val_) - arr_val_.push_back(new json(*v)); - } - bool json::attach_text(char* json_txt) - { - clear(); - - cJSON* jsn = cJSON_Parse(json_txt); - if (jsn) - { - char* text = cJSON_Print(jsn); - if (text) - free(text); - - from_cjson(jsn->child); - cJSON_Delete(jsn); - - return true; - } - - return false; - } - void json::clear(bool as_array) - { - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - for (auto& v : arr_val_) - v->release(); - } - type_ = as_array ? VAL_TYPE_ARRAY : VAL_TYPE_OBJECT; - simple_val_.dval = .0f; - key_ = ""; - strval_ = ""; - arr_val_.clear(); - cur_child_ = -1; - } - std::string json::to_string(void) - { - if (type_ == VAL_TYPE_NULL) - return ""; - if (type_ == VAL_TYPE_BOOL) - return (simple_val_.bval ? "true" : "false"); - if (type_ == VAL_TYPE_INT) - return std::to_string(simple_val_.nval); - if (type_ == VAL_TYPE_FLOAT) - return std::to_string(simple_val_.dval); - if (type_ == VAL_TYPE_STRING) - { - char* u = cJSON_utf8_2_unic(strval_.c_str()); - std::string r(u); - - free(u); - special_char_trans::to_writedown(r); - - return "\"" + r + "\""; - } - - std::string(*k)(json*) = type_ == VAL_TYPE_OBJECT ? json::object_key : json::array_key; - std::string str(type_ == VAL_TYPE_OBJECT ? "{" : "["); - - if (arr_val_.size()) - { - str += k(arr_val_[0]) + arr_val_[0]->to_string(); - for (size_t i = 1; i < arr_val_.size(); ++i) - str += "," + k(arr_val_[i]) + arr_val_[i]->to_string(); - } - str += type_ == VAL_TYPE_OBJECT ? "}" : "]"; - - return str; - } - - std::string& json::key(void) - { - return key_; - } - bool json::is_array(void) - { - return type_ == VAL_TYPE_ARRAY; - } - bool json::is_leaf_node(void) - { - return type_ == VAL_TYPE_BOOL || - type_ == VAL_TYPE_INT || - type_ == VAL_TYPE_FLOAT || - type_ == VAL_TYPE_STRING; - } - - bool json::get_value(const char* key, bool& val) - { - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_BOOL) - { - val = child->simple_val_.bval; - ret = true; - } - child->release(); - } - else if (type_ == VAL_TYPE_BOOL && key_ == key) - { - val = simple_val_.bval; - ret = true; - } - - return ret; - } - bool json::get_value(const char* key, int& val) - { - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_INT) - { - val = child->simple_val_.nval; - ret = true; - } - child->release(); - } - else if (type_ == VAL_TYPE_INT && key_ == key) - { - val = simple_val_.nval; - ret = true; - } - - return ret; - } - bool json::get_value(const char* key, double& val) - { - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_FLOAT) - { - val = child->simple_val_.dval; - ret = true; - } - child->release(); - } - else if (type_ == VAL_TYPE_FLOAT && key_ == key) - { - val = simple_val_.dval; - ret = true; - } - - return ret; - } - bool json::get_value(const char* key, std::string& val) - { - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_STRING) - { - val = child->strval_; - ret = true; - } - child->release(); - } - else if (type_ == VAL_TYPE_STRING && key_ == key) - { - val = strval_; - ret = true; - } - - return ret; - } - bool json::get_value(const char* key, json*& val) - { - bool ret = false; - json* child = find_child(key); - - if (child) - { - if (child->type_ == VAL_TYPE_OBJECT) - { - val = child; - ret = true; - } - else - { - child->release(); - } - } - - return ret; - } - - size_t json::children(void) - { - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - return arr_val_.size(); - else - return -1; - } - json* json::child(size_t ind) - { - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - if (ind >= 0 && ind < arr_val_.size()) - { - arr_val_[ind]->add_ref(); - - return arr_val_[ind]; - } - } - - return nullptr; - } - json* json::first_child(void) - { - cur_child_ = 0; - if (type_ == VAL_TYPE_OBJECT || type_ == VAL_TYPE_ARRAY) - { - if (arr_val_.size()) - { - arr_val_[0]->add_ref(); - - return arr_val_[0]; - } - } - - return nullptr; - // leaf node, return self - //add_ref(); - - //return this; - } - json* json::next_child(void) - { - if (type_ == VAL_TYPE_OBJECT || type_ == VAL_TYPE_ARRAY) - { - if (++cur_child_ < arr_val_.size()) - { - arr_val_[cur_child_]->add_ref(); - - return arr_val_[cur_child_]; - } - } - - return nullptr; - } - - bool json::set_value(const char* key, bool val) - { - if (type_ != VAL_TYPE_OBJECT) - return false; - - json* child = find_child(key); - - if (child) - { - child->clear(); - child->type_ = VAL_TYPE_BOOL; - child->key() = key ? key : ""; - child->simple_val_.bval = val; - child->release(); - } - else - { - child = new json(key, val); - arr_val_.push_back(child); - } - - return true; - } - bool json::set_value(const char* key, int val) - { - if (type_ != VAL_TYPE_OBJECT) - return false; - - json* child = find_child(key); - - if (child) - { - child->clear(); - child->type_ = VAL_TYPE_INT; - child->key() = key ? key : ""; - child->simple_val_.nval = val; - child->release(); - } - else - { - child = new json(key, val); - arr_val_.push_back(child); - } - - return true; - } - bool json::set_value(const char* key, double val) - { - if (type_ != VAL_TYPE_OBJECT) - return false; - - json* child = find_child(key); - - if (child) - { - child->clear(); - child->type_ = VAL_TYPE_FLOAT; - child->key() = key ? key : ""; - child->simple_val_.dval = val; - child->release(); - } - else - { - child = new json(key, val); - arr_val_.push_back(child); - } - - return true; - } - bool json::set_value(const char* key, const char* val) - { - if (type_ != VAL_TYPE_OBJECT) - return false; - - json* child = find_child(key); - - if (child) - { - child->clear(); - child->type_ = VAL_TYPE_STRING; - child->key() = key ? key : ""; - child->strval_ = val ? val : ""; - child->release(); - } - else - { - child = new json(key, val); - arr_val_.push_back(child); - } - - return true; - } - bool json::set_value(const char* key, json* val) - { - if (type_ != VAL_TYPE_OBJECT) - return false; - - for (size_t i = 0; i < arr_val_.size(); ++i) - { - if (arr_val_[i]->key() == key) - { - arr_val_[i]->release(); - arr_val_[i] = val; - val->add_ref(); - return true; - } - } - - arr_val_.push_back(val); - val->key() = key; - val->add_ref(); - - return true; - } - - json& json::operator+=(bool val) - { - if (type_ == VAL_TYPE_ARRAY) - { - json* child = new json(nullptr, val); - arr_val_.push_back(child); - } - - return *this; - } - json& json::operator+=(int val) - { - if (type_ == VAL_TYPE_ARRAY) - { - json* child = new json(nullptr, val); - arr_val_.push_back(child); - } - - return *this; - } - json& json::operator+=(double val) - { - if (type_ == VAL_TYPE_ARRAY) - { - json* child = new json(nullptr, val); - arr_val_.push_back(child); - } - - return *this; - } - json& json::operator+=(const char* val) - { - if (type_ == VAL_TYPE_ARRAY) - { - json* child = new json(nullptr, val); - arr_val_.push_back(child); - } - - return *this; - } - json& json::operator+=(json* val) - { - if (type_ == VAL_TYPE_ARRAY) - { - val->add_ref(); - arr_val_.push_back(val); - } - - return *this; - } - - json& json::operator-=(int ind) - { - remove(ind); - - return *this; - } - bool json::remove(const char* key) - { - json* child = find_child(key, true); - - if (child) - { - child->release(); - return true; - } - else - { - return false; - } - } - bool json::remove(json* child) - { - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - for (size_t i = 0; i < arr_val_.size(); ++i) - { - if (arr_val_[i] == child) - { - arr_val_[i]->release(); - arr_val_.erase(arr_val_.begin() + i); - - return true; - } - } - } - - return false; - } - bool json::remove(int ind) - { - bool ret = false; - - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - if (ind >= 0 && ind < arr_val_.size()) - { - arr_val_[ind]->release(); - arr_val_.erase(arr_val_.begin() + ind); - ret = true; - } - } - - return ret; - } - - int json::index(json* child) - { - if (type_ == VAL_TYPE_ARRAY || type_ == VAL_TYPE_OBJECT) - { - for (int i = 0; i < arr_val_.size(); ++i) - { - if (arr_val_[i] == child) - return i; - } - } - - return -1; - } - int json::index_move_to(json* child, int ind) - { - int i = index(child); - - if (i == -1) - return -1; - - arr_val_.erase(arr_val_.begin() + i); - if (ind < 0) - ind = 0; - if (ind > arr_val_.size()) - ind = arr_val_.size(); - arr_val_.insert(arr_val_.begin() + ind, child); - - return ind; - } - - bool json::value(bool& val) - { - bool ret = false; - - if (is_leaf_node() && type_ == VAL_TYPE_BOOL) - { - val = simple_val_.bval; - ret = true; - } - - return ret; - } - bool json::value(int& val) - { - bool ret = false; - - if (is_leaf_node() && type_ == VAL_TYPE_INT) - { - val = simple_val_.nval; - ret = true; - } - - return ret; - } - bool json::value(double& val) - { - bool ret = false; - - if (is_leaf_node() && type_ == VAL_TYPE_FLOAT) - { - val = simple_val_.dval; - ret = true; - } - - return ret; - } - bool json::value(std::string& val) - { - bool ret = false; - - if (is_leaf_node() && type_ == VAL_TYPE_STRING) - { - val = strval_; - ret = true; - } - - return ret; - } - json& json::operator=(bool val) - { - if (is_leaf_node()) - { - simple_val_.bval = val; - type_ = VAL_TYPE_BOOL; - } - - return *this; - } - json& json::operator=(int val) - { - if (is_leaf_node()) - { - simple_val_.nval = val; - type_ = VAL_TYPE_INT; - } - - return *this; - } - json& json::operator=(double val) - { - if (is_leaf_node()) - { - simple_val_.dval = val; - type_ = VAL_TYPE_FLOAT; - } - - return *this; - } - json& json::operator=(const char* val) - { - if (is_leaf_node()) - { - strval_ = val ? val : ""; - type_ = VAL_TYPE_STRING; - } - - return *this; - } -} - - - -namespace gb -{ - static char base64_default_table[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; - - base64::base64() : padding_char_('=') - { - base64_ind_[0] = base64_char_[0] = 0; - - initialize_base64_table(base64_default_table); - } - base64::~base64() - {} - - bool base64::is_valid_base64_table(const char* table) - { - bool valid = false; - - if (table && strlen(table) >= 64) - { - char repeat[4] = { 0 }; - - valid = true; - for (int i = 0; i < 63; ++i) - { - repeat[0] = table[i]; - if (strstr(table + i + 1, repeat)) - { - valid = false; - break; - } - } - } - - return valid; - } - bool base64::initialize_base64_table(const char* table) - { - if (!table || strlen(table) < 64) - { - if (memcmp(base64_default_table, base64_char_, 64) == 0) - { - return !table; - } - - memcpy(base64_char_, base64_default_table, 64); - } - else - { - if (memcmp(base64_char_, table, 64) == 0) - { - return true; - } - else if (!is_valid_base64_table(table)) - return false; - - memcpy(base64_char_, table, 64); - } - base64_char_[64] = base64_char_[65] = 0; - - // initialize base64_index - memset(base64_ind_, 0, sizeof(base64_ind_)); - for (int i = 0; i < 64; ++i) - { - base64_ind_[base64_char_[i]] = i; - } - - // padding char - padding_char_ = '='; - if (base64_ind_[padding_char_]) - { - for (padding_char_ = 0x21; padding_char_ < 0x7e && base64_ind_[padding_char_] && padding_char_ != base64_char_[0]; ++padding_char_); - } - - return padding_char_ < 0x7e; - } - - bool base64::set_base64_table(const char* table) - { - return initialize_base64_table(table ? table : base64_default_table); - } - std::string base64::encode(const char* data, size_t bytes, unsigned int line_bytes, bool need_padding) - { - char* str = (char*)malloc(bytes * 2 + 3); - unsigned char c1 = 0, c2 = 0, c3 = 0; - unsigned long line_len = 0; - unsigned long words = bytes / 3; - int rest = bytes % 3, - pos = 0; - std::string ret(""); - - for (unsigned long i = 0; i < words; ++i) - { - // fetch 3 letters - c1 = *data++; - c2 = *data++; - c3 = *data++; - - // encoding into 4-bytes - str[pos++] = base64_char_[c1 >> 2]; - str[pos++] = base64_char_[((c1 << 4) | (c2 >> 4)) & 0x3f]; - str[pos++] = base64_char_[((c2 << 2) | (c3 >> 6)) & 0x3f]; - str[pos++] = base64_char_[c3 & 0x3f]; - line_len += 4; - - // new line ... - if ((unsigned int)line_len > line_bytes - 4) - { - str[pos++] = '\r'; - str[pos++] = '\n'; - line_len = 0; - } - } - - // rest ... - if (rest == 1) - { - c1 = *data++; - str[pos++] = base64_char_[(c1 & 0xfc) >> 2]; - str[pos++] = base64_char_[((c1 & 0x03) << 4)]; - if (need_padding) - { - str[pos++] = padding_char_; - str[pos++] = padding_char_; - } - } - else if (rest == 2) - { - c1 = *data++; - c2 = *data++; - str[pos++] = base64_char_[(c1 & 0xfc) >> 2]; - str[pos++] = base64_char_[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)]; - str[pos++] = base64_char_[((c2 & 0x0f) << 2)]; - if (need_padding) - { - str[pos++] = padding_char_; - } - } - if (pos > 0) - { - str[pos++] = 0; - ret = std::string(str, pos - 1); - } - free(str); - - return std::move(ret); - } - std::string base64::decode(const char* data, size_t bytes) - { - char* str = (char*)malloc(bytes + 1); - int pos = 0, - shifts = 18, - value = 0; - std::string ret(""); - - for (int i = 0; i < (int)bytes; ++i) - { - if (*data != '\r' && *data != '\n') - { - if (*data == padding_char_) - { - break; - } - - value += base64_ind_[*data] << shifts; - if (shifts == 0) - { - shifts = 18; - str[pos++] = (value >> 16) & 0x0ff; - str[pos++] = (value >> 8) & 0x0ff; - str[pos++] = (value >> 0) & 0x0ff; - value = 0; - } - else - { - shifts -= 6; - } - } - data++; - } - - if (shifts == 12 || shifts == 6) - { - str[pos++] = (value >> 16) & 0x0ff; - } - else if (shifts == 0) - { - str[pos++] = (value >> 16) & 0x0ff; - str[pos++] = (value >> 8) & 0x0ff; - } - - if (pos > 0) - { - str[pos++] = 0; - ret = std::string(str, pos - 1); - } - free(str); - - return std::move(ret); - } -} - -namespace updater -{ - static std::string hg_model_from_pid(const char* pid) - { - if (strcmp(pid, "7823") == 0) - return "G200"; - - char m[] = { 'G', pid[0], '0', '0', 0}; - - return std::string(m) + " - " + pid; - } - static std::string hv_model_from_pid(const char* pid) - { - std::string m(""); - if (strcmp(pid, "1000") == 0) - m = "HW-1000NS"; - else if (strcmp(pid, "1002") == 0) - m = "HW-1000"; - else if (strcmp(pid, "7000") == 0) - m = "HW-7000NS"; - else if (strcmp(pid, "7002") == 0) - m = "HW-7000"; - else if (strcmp(pid, "7039") == 0) - m = "HW-7000NS"; - else - m = std::string("HW-") + pid; - - return m + " - " + pid; - } - static std::string lsc_model_from_pid(const char* pid) - { - if (strcmp(pid, "8200") == 0) - return "G42S - 8200"; - else - { - char m[] = {'G', pid[1], pid[2], 'S', 0}; - - return std::string(m) + " - " + pid; - } - } - static std::string scanner_chinese_name_2_model(const char* cn) - { - static const char* hg = "\345\215\216\351\253\230", - * hw = "\346\261\211\347\216\213", - * lsc = "\347\253\213\346\200\235\350\276\260", - * smy = "\346\211\253\346\217\217\344\273\252\342\200\224G", - * f = strstr(cn, hg); - std::string model(""); - std::string(* model_from_pid)(const char* pid) = nullptr; - - if (f == cn) - { - model = "HUAGOSCAN "; - model_from_pid = hg_model_from_pid;; - } - else if (strstr(cn, hw) == cn) - { - model = "Hanvon "; - model_from_pid = hv_model_from_pid;; - } - else if (strstr(cn, lsc) == cn) - { - model = "LANXUMSCAN "; - model_from_pid = lsc_model_from_pid;; - } - else - return ""; - - f = strstr(cn, smy); - if (!f) - return ""; - - f += strlen(smy); - model += model_from_pid(f); - - return model; - } -} -namespace gb -{ - std::string sane_config_schm::opt_data_appendix_("_data"); - std::string sane_config_schm::opt_def_id_appendix_("_id"); - std::string sane_config_schm::opt_def_val_appendix_("_val"); - std::string sane_config_schm::opt_def_type_appendix_("_type"); - std::string sane_config_schm::opt_def_title_appendix_("_title"); - - sane_config_schm::sane_config_schm(scanner_cfg* scanner) : jsn_(nullptr), bkp_(nullptr), in_setting_(false), scheme_name_("") - , scanner_(scanner) - { - char empty[8] = { "{}" }; - jsn_ = new gb::json(); - jsn_->attach_text(empty); - if (scanner_) - { - scanner_->add_ref(); - def_val_ = scanner_->get_option_default_value(); - } - else - def_val_ = new gb::json(); - } - sane_config_schm::~sane_config_schm() - { - clear(); - def_val_->release(); - if (scanner_) - scanner_->release(); - } - - bool sane_config_schm::hex(unsigned char ch, unsigned char* val) - { - bool ret = true; - - if (ch >= '0' && ch <= '9') - ch -= '0'; - else if (ch >= 'a' && ch <= 'f') - ch = ch - 'a' + 10; - else if (ch >= 'A' && ch <= 'F') - ch = ch - 'A' + 10; - else - ret = false; - - if (ret && val) - { - *val &= 0x0f0; - *val |= ch; - } - - return ret; - } - bool sane_config_schm::hex_char(const char* data, unsigned char* val) - { - unsigned char v = 0; - bool ret = false; - - if (sane_config_schm::hex(*data++, &v)) - { - v <<= 4; - if (sane_config_schm::hex(*data++, &v)) - { - if (val) - *val = v; - - ret = true; - } - } - - return ret; - } - std::string sane_config_schm::to_hex_letter(const char* data, size_t bytes) - { - std::string hex(""); - const unsigned char* ptr = (const unsigned char*)data; - char buf[8] = { 0 }; - - for (size_t i = 0; i < bytes; ++i) - { - sprintf(buf, "%02X", ptr[i]); - hex += buf; - } - - return hex; - } - std::string sane_config_schm::from_hex_letter(const char* data, size_t bytes) - { - std::string stream(""); - - bytes /= 2; - for (size_t i = 0; i < bytes; ++i) - { - unsigned char ch = 0; - if (!sane_config_schm::hex_char(data, &ch)) - break; - stream.append(1, ch); - data += 2; - } - - return stream; - } - bool sane_config_schm::is_option_data(std::string& name) - { - size_t pos = name.find(sane_config_schm::opt_data_appendix_); - - if (pos != std::string::npos) - { - if (pos + sane_config_schm::opt_data_appendix_.length() == name.length()) - { - name.erase(pos); - - return true; - } - } - - return false; - } - void sane_config_schm::set_default_value(json* jsn, int id, const char* name, const char* title, void* data, size_t bytes, int type) - { - std::string key(name); - - jsn->set_value(std::to_string(id).c_str(), name); - jsn->set_value((name + sane_config_schm::opt_def_id_appendix_).c_str(), id); - jsn->set_value((name + sane_config_schm::opt_def_val_appendix_).c_str(), sane_config_schm::to_hex_letter((const char*)data, bytes).c_str()); - jsn->set_value((name + sane_config_schm::opt_def_type_appendix_).c_str(), type); - jsn->set_value((name + sane_config_schm::opt_def_title_appendix_).c_str(), title); - } - int sane_config_schm::option_name_2_id(json* jsn, const char* name) - { - int id = -1; - - return jsn->get_value((std::string(name) + sane_config_schm::opt_def_id_appendix_).c_str(), id) ? id : -1; - } - int sane_config_schm::option_type(json* jsn, const char* name) - { - int id = -1; - - return jsn->get_value((std::string(name) + sane_config_schm::opt_def_type_appendix_).c_str(), id) ? id : -1; - } - std::string sane_config_schm::option_title(json* jsn, const char* name) - { - std::string title(""); - - jsn->get_value((std::string(name) + sane_config_schm::opt_def_title_appendix_).c_str(), title); - - return std::move(title); - } - std::string sane_config_schm::option_default_value(json* jsn, const char* name) - { - std::string val(""); - - return jsn->get_value((std::string(name) + sane_config_schm::opt_def_val_appendix_).c_str(), val) ? std::move(val) : ""; - } - std::string sane_config_schm::sane_option_value_2_string(void* val, size_t bytes, int type) - { - char buf[80] = { 0 }; - - switch (type) - { - case SANE_TYPE_BOOL: - return *((SANE_Bool*)val) == SANE_TRUE ? "true" : "false"; - break; - case SANE_TYPE_INT: - return std::to_string(*(SANE_Int*)val); - break; - case SANE_TYPE_FIXED: - sprintf_s(buf, _countof(buf) - 1, "%f", SANE_UNFIX(*(SANE_Fixed*)val)); - break; - case SANE_TYPE_STRING: - return std::string((char*)val, bytes); - } - - return buf; - } - - void sane_config_schm::clear() - { - if (jsn_) - jsn_->release(); - jsn_ = nullptr; - if (bkp_) - bkp_->release(); - bkp_ = nullptr; - } - std::string sane_config_schm::default_value(const char* hex_title) - { - return sane_config_schm::option_default_value(def_val_, hex_title); - } - - sane_config_schm* sane_config_schm::copy(void) - { - sane_config_schm *cp = new sane_config_schm(scanner_); - - cp->scheme_name_ = scheme_name_; - cp->file_ = file_; - if(jsn_) - cp->jsn_->copy_from(*jsn_); - if (bkp_) - { - cp->bkp_ = new gb::json(); - cp->bkp_->copy_from(*bkp_); - } - cp->def_val_->release(); - cp->def_val_ = def_val_; - def_val_->add_ref(); - - return cp; - } - bool sane_config_schm::load_from_file(const char* file) - { - clear(); - - std::string cont(""); - - file_ = file; - if (gb::load_mini_file(file, cont)) - return false; - - return load_from_mem(cont.c_str()); - } - bool sane_config_schm::load_from_mem(const char* mem, bool in_b64) - { - gb::base64 b64; - std::string stream(in_b64 ? b64.decode(mem, strlen(mem)) : mem); - - clear(); - jsn_ = new gb::json(); - if (!jsn_->attach_text(&stream[0])) - { - jsn_->release(); - jsn_ = NULL; - - return false; - } - - return true; - } - bool sane_config_schm::save_to(const char* file) - { - bool ret = false; - std::string encode(to_text_stream()); - - if (!file || *file == 0) - file = file_.c_str(); - - if (encode.length()) - { - FILE* dst = fopen(file, "wb"); - - if (dst) - { - fwrite(encode.c_str(), 1, encode.length(), dst); - fclose(dst); - ret = true; - } - } - - return ret; - } - void sane_config_schm::set_default_value(int sn, const char* name, const char* title, const char* val, size_t bytes, int type) - { - sane_config_schm::set_default_value(def_val_, sn, name, title, (void*)val, bytes, type); - } - bool sane_config_schm::first_config(std::string& name, std::string& val) - { - bool ret = false; - json* child = nullptr; - std::string raw_v(""); - - if (jsn_ && (child = jsn_->first_child())) - { - name = child->key(); - child->value(raw_v); - val = sane_config_schm::from_hex_letter(raw_v.c_str(), raw_v.length()); - - ret = true; - } - - return ret; - } - bool sane_config_schm::next_config(std::string& name, std::string& val) - { - bool ret = false; - json* child = nullptr; - std::string raw_v(""); - - if (jsn_ && (child = jsn_->next_child())) - { - name = child->key(); - child->value(raw_v); - val = sane_config_schm::from_hex_letter(raw_v.c_str(), raw_v.length()); - - ret = true; - } - - return ret; - } - bool sane_config_schm::get_config(const char* name, std::string& val) - { - bool ret = jsn_ ? jsn_->get_value(name, val) : false; - - if(!ret && def_val_) - ret = def_val_->get_value(name, val); - - if(ret) - val = sane_config_schm::from_hex_letter(val.c_str(), val.length()); - - return ret; - } - void sane_config_schm::begin_setting(bool restore) - { - if (bkp_) - bkp_->release(); - bkp_ = jsn_; - in_setting_ = true; - jsn_ = new gb::json(); - if (!restore && bkp_) - { - jsn_->copy_from(*bkp_); - } - } - void sane_config_schm::config_changed(const char* name, const char* val, size_t bytes, bool extra) - { - std::string hex_v(to_hex_letter(val, bytes)); - - if (extra) - { - jsn_->set_value((name + sane_config_schm::opt_data_appendix_).c_str(), hex_v.c_str()); - } - else - { - std::string def = default_value(name); - if (hex_v == def) - { - jsn_->remove(name); - jsn_->remove((name + sane_config_schm::opt_data_appendix_).c_str()); - } - else - jsn_->set_value(name, hex_v.c_str()); - } - } - void sane_config_schm::config_changed(int sn, const char* val, size_t bytes, bool extra) - { - std::string name(""); - - def_val_->get_value(std::to_string(sn).c_str(), name); - if (!name.empty()) - { - config_changed(name.c_str(), val, bytes, extra); - } - } - void sane_config_schm::remove_config(const char* name) - { - if (jsn_) - jsn_->remove(name); - } - void sane_config_schm::set_value(const char* name, const char* val, size_t bytes, bool extra) - { - std::string hex_v(to_hex_letter(val, bytes)); - - if (extra) - jsn_->set_value((name + sane_config_schm::opt_data_appendix_).c_str(), hex_v.c_str()); - else - jsn_->set_value(name, hex_v.c_str()); - } - bool sane_config_schm::has_changed(int* items) - { - if(items) - *items = jsn_ ? jsn_->children() : 0; - - if(!bkp_) - return false; - - std::map old; - std::string n(""), v(""); - json* child = nullptr; - if((child = bkp_->first_child())) - { - do - { - child->value(v); - old[child->key()] = std::move(v); - child->release(); - }while((child = bkp_->next_child())); - } - - if((child = jsn_->first_child())) - { - do - { - n = child->key(); - if(old.count(n) == 0) - { - child->release(); - return true; - } - child->value(v); - if(old[n]!=v) - { - child->release(); - return true; - } - - child->release(); - old.erase(n); - } while ((child = jsn_->next_child())); - } - - return old.size() > 0; - } - void sane_config_schm::end_setting(bool cancel) - { - if (in_setting_) - { - if (cancel) - { - jsn_->release(); - jsn_ = bkp_; - bkp_ = nullptr; - } - else if (bkp_) - { - bkp_->release(); - bkp_ = nullptr; - } - } - in_setting_ = false; - } - int sane_config_schm::id_from_name(const char* name) - { - return sane_config_schm::option_name_2_id(def_val_, name); - } - std::string sane_config_schm::to_text_stream(bool b64, bool with_ver) - { - if (jsn_) - { - if(with_ver) - { - char ver[40] = { 0 }; - sprintf(ver, "%u.%u", VERSION_MAIN, VERSION_SUB); - jsn_->set_value("ver", ver); - } - - std::string cont(""); - //if (jsn_->is_leaf_node()) - //{ - // jsn_->value(cont); - // cont.insert(0, "{\"" + jsn_->key() + "\":\""); - // cont += "\"}"; - //} - //else - cont = jsn_->to_string(); - if (b64) - { - gb::base64 b64; - - cont = b64.encode(cont.c_str(), cont.length()); - } - - return cont; - } - else - return ""; - } - std::string sane_config_schm::get_version(void) - { - std::string ver(""); - - if (jsn_) - jsn_->get_value("ver", ver); - - return ver; - } - std::string sane_config_schm::get_scheme_name(void) - { - return scheme_name_; - } - void sane_config_schm::set_scheme_name(const char* name) - { - scheme_name_ = name ? name : ""; - } - - std::string sane_config_schm::auto_gen_scheme_name(const char* (__stdcall* lang_trans)(const char*, bool/*true - default language to cur language*/, void*), void* param, bool replace_name) - { - std::string name(""), key(""), val(""), add(""); - int cnt = 0; - - if (first_config(key, val)) - { - do - { - if (cnt++ > 3) - break; - - SANE_Value_Type type = (SANE_Value_Type)sane_config_schm::option_type(def_val_, key.c_str()); - if (type == SANE_TYPE_STRING) - name += add + lang_trans(val.c_str(), true, param); - else - name += add + sane_config_schm::option_title(def_val_, key.c_str()) + "(" + sane_config_schm::sane_option_value_2_string(&val[0], val.length(), type) + ")"; - add = "+"; - } while (next_config(key, val)); - } - - if (name.empty()) - name = lang_trans(scanner_cfg::default_setting_name_.c_str(), true, param); - - cnt = 0; - if (scanner_) - { - sane_config_schm* cfg = scanner_->get_scheme(name.c_str()); - while (cfg) - { - cfg->release(); - cfg = scanner_->get_scheme((name + "(" + std::to_string(++cnt) + ")").c_str()); - } - if (cnt) - name += "(" + std::to_string(++cnt) + ")"; - } - if(replace_name) - scheme_name_ = name; - - return std::move(name); - } - - - - /////////////////////////////////////////////////////////////////////////////////// - // scanner_cfg - std::string scanner_cfg::global_name_ = "global"; - std::string scanner_cfg::cur_sel_ = "cur"; - std::string scanner_cfg::default_setting_name_ = "\xE9\xBB\x98\xE8\xAE\xA4\xE8\xAE\xBE\xE7\xBD\xAE"; // utf-8: 默认设置 - - scanner_cfg::scanner_cfg() : path_(""), scanner_name_(""), global_(new json()), lang_trans_(scanner_cfg::language_trans), lang_param_(nullptr) - { - opt_default_value_ = new json(); - - init_version(); - init_select(); - } - scanner_cfg::~scanner_cfg() - { - clear(); - global_->release(); - } - - bool scanner_cfg::update(const char* file, LPUDF func) - { - return false; - } - - const char* __stdcall scanner_cfg::language_trans(const char* in, bool from_def, void* param) - { - return in; - } - - void scanner_cfg::clear(void) - { - global_->set_value("ver", ""); - global_->set_value(scanner_cfg::cur_sel_.c_str(), -1); - - for (size_t i = 0; i < schemes_.size(); ++i) - schemes_[i].schm->release(); - schemes_.clear(); - scanner_name_ = ""; - } - void scanner_cfg::init_version(void) - { - char vstr[40] = { 0 }; - - sprintf(vstr, "%u.%u", VERSION_MAIN, VERSION_SUB); - global_->set_value("ver", vstr); - } - void scanner_cfg::init_select(void) - { - global_->set_value(scanner_cfg::cur_sel_.c_str(), -1); - } - const char* scanner_cfg::trans_language(const char* in, bool from_default) - { - return lang_trans_(in, from_default, lang_param_); - } - - int scanner_cfg::load_file(const char* file) - { - std::string cont(""); - int ret = gb::load_mini_file(file, cont); - - if (ret == 0) - { - const char* name = strrchr(file, PATH_SYMBOL[0]); - if (name++ == nullptr) - name = file; - else - path_ = std::string(file, name - file); - - scanner_name_ = name; - ret = scanner_name_.rfind('.'); - if (ret != std::string::npos) - scanner_name_.erase(ret); - ret = load_mem(cont.c_str());; - } - - return ret; - } - int scanner_cfg::load_mem(const char* mem) - { - json* jsn = new json(*(char**)&mem), * glb = nullptr; - - if (jsn->get_value("global", glb)) - { - int sel = -1; - glb->get_value(scanner_cfg::cur_sel_.c_str(), sel); - glb->release(); - glb = jsn->first_child(); - while ((glb = jsn->next_child())) - { - std::string val(""); - sane_config_schm * cfg = new sane_config_schm(this); - - glb->value(val); - if (cfg->load_from_mem(val.c_str())) - { - val = glb->key(); - val = sane_config_schm::from_hex_letter(val.c_str(), val.length()); - add_scheme(cfg, val.c_str()); - cfg->set_scheme_name(val.c_str()); - } - cfg->release(); - glb->release(); - } - if (sel < 0 || sel >= schemes_.size()) - sel = -1; - global_->set_value(scanner_cfg::cur_sel_.c_str(), sel); - } - else - { - sane_config_schm* cfg = new sane_config_schm(this); - if (cfg->load_from_mem(mem)) - { - cfg->remove_config("ver"); - - std::string name(cfg->auto_gen_scheme_name(lang_trans_, lang_param_)); - add_scheme(cfg); - select_scheme(name.c_str()); - save(); - } - cfg->release(); - } - jsn->release(); - - return 0; - } - int scanner_cfg::save(const char* file) - { - if (!file && path_.empty() && scanner_name_.empty()) - return EINVAL; - - std::string cont(to_text_stream()), - f(file ? file : path_ + scanner_name_ + ".cfg"); - FILE* dst = fopen(f.c_str(), "wb"); - - if (!dst) - return errno; - - fwrite(cont.c_str(), 1, cont.length(), dst); - fclose(dst); - - return 0; - } - void scanner_cfg::set_language_transform(const char* (__stdcall* lang_trans)(const char*, bool/*true - default language to cur language*/, void*), void* param) - { - lang_trans_ = lang_trans ? lang_trans : &scanner_cfg::language_trans; - lang_param_ = param; - } - - json* scanner_cfg::get_option_default_value(void) - { - opt_default_value_->add_ref(); - - return opt_default_value_; - } - void scanner_cfg::get_all_schemes(std::vector& schemes) - { - schemes.push_back(trans_language(scanner_cfg::default_setting_name_.c_str(), true)); - for (auto& v : schemes_) - schemes.push_back(v.name); - } - sane_config_schm* scanner_cfg::get_scheme(const char* scheme_name) - { - sane_config_schm* found = nullptr; - - if (scheme_name && *scheme_name) - { - std::vector::iterator it = std::find(schemes_.begin(), schemes_.end(), scheme_name); - if (it != schemes_.end()) - found = it->schm; - } - else - { - int ind = -1; - - global_->get_value(scanner_cfg::cur_sel_.c_str(), ind); - if (ind >= 0 && ind < schemes_.size()) - found = schemes_[ind].schm; - } - - if (found) - found->add_ref(); - - return found; - } - sane_config_schm* scanner_cfg::create_empty_scheme(bool selected) - { - sane_config_schm* schm = new sane_config_schm(this); - int ind = 1; - std::string prev(trans_language(scanner_cfg::default_setting_name_.c_str(), true)); - - while (std::find(schemes_.begin(), schemes_.end(), (prev + "-" + std::to_string(ind)).c_str()) != schemes_.end()) - ind++; - - prev += "-" + std::to_string(ind); - add_scheme(schm, prev.c_str(), true); - if (selected) - select_scheme(prev.c_str()); - - return schm; - } - std::string scanner_cfg::get_current_scheme_name(void) - { - int ind = -1; - - global_->get_value(scanner_cfg::cur_sel_.c_str(), ind); - if (ind >= 0 && ind < schemes_.size()) - return schemes_[ind].name; - else - return trans_language(scanner_cfg::default_setting_name_.c_str(), true); - } - std::string scanner_cfg::to_text_stream(void) - { - std::string text(""), val(""); - int sel = -1; - - if (!global_->get_value("ver", val) || val.empty()) - init_version(); - if (!global_->get_value(scanner_cfg::cur_sel_.c_str(), sel) || sel >= schemes_.size()) - init_select(); - text = "{\"" + scanner_cfg::global_name_ + "\":" + global_->to_string(); - - for (auto& v : schemes_) - { - if (v.should_rename) - { - v.schm->auto_gen_scheme_name(lang_trans_, lang_param_); - v.name = v.schm->get_scheme_name(); - v.should_rename = false; - } - text += ",\"" + sane_config_schm::to_hex_letter(v.name.c_str(), v.name.length()) + "\":\"" + v.schm->to_text_stream(true, false) + "\""; - } - text += "}"; - - return std::move(text); - } - void scanner_cfg::set_default_value(int id, const char* name, const char* title, void* data, size_t bytes, int type) - { - sane_config_schm::set_default_value(opt_default_value_, id, name, title, data, bytes, type); - } - int scanner_cfg::option_value_type(const char* name) - { - return sane_config_schm::option_type(opt_default_value_, name); - } - std::string scanner_cfg::option_title(const char* name) - { - return sane_config_schm::option_title(opt_default_value_, name); - } - bool scanner_cfg::remove_scheme(const char* scheme_name) - { - std::vector::iterator it = std::find(schemes_.begin(), schemes_.end(), scheme_name); - - if (it != schemes_.end()) - { - int id = it - schemes_.begin(), - ind = -1; - - it->schm->release(); - schemes_.erase(it); - global_->get_value(scanner_cfg::cur_sel_.c_str(), ind); - if (ind == id) - global_->set_value(scanner_cfg::cur_sel_.c_str(), -1); - else if (ind > id) - global_->set_value(scanner_cfg::cur_sel_.c_str(), ind - 1); - - return true; - } - - return false; - } - void scanner_cfg::remove_all_schemes(void) - { - for(auto& v: schemes_) - v.schm->release(); - - schemes_.clear(); - } - bool scanner_cfg::select_scheme(const char* scheme_name) - { - std::vector::iterator it = scheme_name ? std::find(schemes_.begin(), schemes_.end(), scheme_name) : schemes_.end(); - - if (it == schemes_.end()) - global_->set_value(scanner_cfg::cur_sel_.c_str(), -1); - else - global_->set_value(scanner_cfg::cur_sel_.c_str(), (int)(it - schemes_.begin())); - - return true; - } - - sane_config_schm* scanner_cfg::copy_scheme(const char* cp_from_name) // for UI setting, call release() if not use anymore - { - if (!cp_from_name || *cp_from_name == 0 || - std::string(trans_language(scanner_cfg::default_setting_name_.c_str(), true)) == cp_from_name) - { - sane_config_schm* schm = new sane_config_schm(this); - - schm->set_scheme_name(trans_language(scanner_cfg::default_setting_name_.c_str(), true)); - - return schm; - } - else - { - std::vector::iterator it = std::find(schemes_.begin(), schemes_.end(), cp_from_name); - if (it == schemes_.end()) - return nullptr; - - return it->schm->copy(); - } - } - bool scanner_cfg::add_scheme(sane_config_schm* schm, const char* name, bool should_rename) - { - CFGSCHM cs; - - cs.name = name ? name : schm->get_scheme_name(); - if(cs.name.empty() || cs.name == scanner_cfg::global_name_) - return false; - - if (std::find(schemes_.begin(), schemes_.end(), cs.name.c_str()) != schemes_.end()) - return false; - - cs.schm = schm; - cs.should_rename = should_rename; - - schemes_.push_back(cs); - schm->set_scheme_name(cs.name.c_str()); - schm->add_ref(); - - return true; - } - bool scanner_cfg::rename_scheme(const char* from, const char* to) - { - if (to && (strcmp(to, trans_language(scanner_cfg::default_setting_name_.c_str(), true)) == 0 || std::find(schemes_.begin(), schemes_.end(), to) != schemes_.end())) - return false; - - for(auto& v: schemes_) - { - if(v.name == from) - { - v.name = to; - v.should_rename = false; - v.schm->set_scheme_name(to); - return true; - } - } - - return false; - } -} diff --git a/sane/gb_json.h b/sane/gb_json.h deleted file mode 100644 index e53787f..0000000 --- a/sane/gb_json.h +++ /dev/null @@ -1,313 +0,0 @@ -#pragma once - -#if defined(WIN32) || defined(_WIN64) -#include -#include "../../code_device/hgsane/cJSON.h" -#define PATH_SYMBOL "\\" -#else -#include "cJSON.h" -#define PATH_SYMBOL "/" -#define NULL nullptr -#define DWORD_PTR char* -#define _countof(a) sizeof(a) / sizeof(a[0]) -#endif - -// -#include -#include -#include -#include - -namespace gb -{ - class scanner_cfg; - class refer - { - volatile long ref_; - - protected: - refer(); - virtual ~refer(); - - public: - long add_ref(void); - long release(void); - }; - - - class json : public refer - { - enum val_type - { - VAL_TYPE_NULL = 0, - VAL_TYPE_BOOL, - VAL_TYPE_INT, - VAL_TYPE_FLOAT, - VAL_TYPE_STRING, - VAL_TYPE_OBJECT, - VAL_TYPE_ARRAY, - }; - val_type type_; - std::string key_; - union - { - bool bval; - int nval; - double dval; - }simple_val_; - std::string strval_; - std::vector arr_val_; - size_t cur_child_; - - static std::string object_key(json* jsn); - static std::string array_key(json* jsn); - - void from_cjson(cJSON* cj); - json* find_child(const char* key, bool remove = false); - - public: - json(char* json_txt = 0); - - protected: - json(const char* key, bool val); - json(const char* key, int val); - json(const char* key, double val); - json(const char* key, const char* val); - json(json& r); - ~json(); - - public: - // parse/un-parse ... - void copy_from(json& r); - bool attach_text(char* json_txt); - void clear(bool as_array = false); - std::string to_string(void); - - // attributes ... - std::string& key(void); - bool is_array(void); - bool is_leaf_node(void); // whether this object is a leaf node contains final value - - // value access ... - bool get_value(const char* key, bool& val); - bool get_value(const char* key, int& val); - bool get_value(const char* key, double& val); - bool get_value(const char* key, std::string& val); - bool get_value(const char* key, json*& val); - - // enumeration ... - size_t children(void); // return children count if was object or array, or else -1 returned - json* child(size_t ind); - json* first_child(void); - json* next_child(void); - - // change the item matching 'key', otherwise add a new item - bool set_value(const char* key, bool val); - bool set_value(const char* key, int val); - bool set_value(const char* key, double val); - bool set_value(const char* key, const char* val); - bool set_value(const char* key, json* val); - - // operator+= only for array - json& operator+=(bool val); - json& operator+=(int val); - json& operator+=(double val); - json& operator+=(const char* val); - json& operator+=(json* val); - - // remove item - json& operator-=(int ind); - bool remove(const char* key); - bool remove(json* child); - bool remove(int ind); - - // position management - int index(json* child); - int index_move_to(json* child, int ind); - - // leaf node value ... - bool value(bool& val); - bool value(int& val); - bool value(double& val); - bool value(std::string& val); - json& operator=(bool val); - json& operator=(int val); - json& operator=(double val); - json& operator=(const char* val); - }; - - class base64 - { - char base64_ind_[128]; - char base64_char_[80]; - char padding_char_; - - bool is_valid_base64_table(const char* table); - bool initialize_base64_table(const char* table); - - public: - base64(); - ~base64(); - - public: - bool set_base64_table(const char* table = NULL); - std::string encode(const char* data, size_t bytes, unsigned int line_bytes = -1, bool need_padding = true); - std::string decode(const char* data, size_t bytes); - }; - - // NOTE: 2021-01-28 all stored string value are in default language (i.e. Chinese-Simplified), user should call app_language::to_default_language/from_default_language for real value - class sane_config_schm : public refer - { - std::string scheme_name_; - scanner_cfg *scanner_; - std::string file_; - json* jsn_; - json* bkp_; - json* def_val_; // name_id: id, name_val: val - bool in_setting_; - - void clear(); - std::string default_value(const char* name); - - protected: - ~sane_config_schm(); - - public: - sane_config_schm(scanner_cfg* scanner = nullptr); - - static std::string opt_data_appendix_; - static std::string opt_def_id_appendix_; - static std::string opt_def_val_appendix_; - static std::string opt_def_type_appendix_; - static std::string opt_def_title_appendix_; - - static bool hex(unsigned char ch, unsigned char* val); - static bool hex_char(const char* data, unsigned char* val); - static std::string to_hex_letter(const char* data, size_t bytes); - static std::string from_hex_letter(const char* data, size_t bytes); - static bool is_option_data(std::string& name); // reset baase option name into 'name' if name was option data, and return true - static void set_default_value(json* jsn, int id, const char* name, const char* title, void* data, size_t bytes, int type); - static int option_name_2_id(json* jsn, const char* name); - static int option_type(json* jsn, const char* name); - static std::string option_title(json* jsn, const char* name); - static std::string option_default_value(json* jsn, const char* name); - static std::string sane_option_value_2_string(void* val, size_t bytes, int type); - - - public: - sane_config_schm* copy(void); - bool load_from_file(const char* file); - bool load_from_mem(const char* mem, bool in_b64 = true); - bool save_to(const char* file); - void set_default_value(int sn, const char* name, const char* title, const char* val, size_t bytes, int type); - bool first_config(std::string& name, std::string& val); - bool next_config(std::string& name, std::string& val); - bool get_config(const char* name, std::string& val); - void begin_setting(bool restore = false); - void config_changed(const char* name, const char* val, size_t bytes, bool extra = false); - void config_changed(int sn, const char* val, size_t bytes, bool extra = false); - void remove_config(const char* name); - void set_value(const char* name, const char* val, size_t bytes, bool extra = false); - bool has_changed(int* items = nullptr); - void end_setting(bool cancel); - int id_from_name(const char* name); - std::string to_text_stream(bool b64 = true, bool with_ver = true); - std::string get_version(void); - std::string get_scheme_name(void); - void set_scheme_name(const char* name); - - std::string auto_gen_scheme_name(const char* (__stdcall* lang_trans)(const char*, bool/*true - default language to cur language*/, void*), void* param, bool replace_name = true); - }; - - class scanner_cfg : public refer - { - // format: in base64 - // - // { - // "global": { - // "ver": "4.33", - // "cur": -1 - // }, - // "scheme_1": sane_config_schm*, - // "scheme_2": sane_config_schm*, - // "scheme_3": sane_config_schm*, - // ... - // } - // - std::string path_; - std::string scanner_name_; // scanner type: HUAGOSCAN G100 - 0100 - json *global_; // version, current scheme, ... - json *opt_default_value_; - - const char* (__stdcall* lang_trans_)(const char*, bool/*true - default language to cur language*/, void*); - void* lang_param_; - - typedef struct _cfg_schm - { - std::string name; - bool should_rename; - sane_config_schm* schm; - - struct _cfg_schm() - { - name = ""; - should_rename = false; - schm = nullptr; - } - bool operator==(const char* n) - { - return name == n; - } - }CFGSCHM; - std::vector schemes_; - - static const char* __stdcall language_trans(const char* in, bool from_def, void* param); - - void clear(void); - void init_version(void); - void init_select(void); - const char* trans_language(const char* in, bool from_default); - - protected: - ~scanner_cfg(); - - public: - scanner_cfg(); - - typedef struct _update_func - { - void(* trans_number)(const char* name, std::string& val, void* param); - const char* (* title2name)(const char* title, void* param); - std::string discard_msg; // update failed items ... - void* func_param; - }UDF, *LPUDF; - static bool update(const char* file, LPUDF func); - - static std::string global_name_; - static std::string cur_sel_; - static std::string default_setting_name_; - - public: - int load_file(const char* file); - int load_mem(const char* mem); - int save(const char* file = nullptr); - void set_language_transform(const char* (__stdcall* lang_trans)(const char*, bool/*true - default language to cur language*/, void*), void* param); - - json* get_option_default_value(void); - void get_all_schemes(std::vector& schemes); // return all schemes name queue, the first is always be 'Default settings' - sane_config_schm* get_scheme(const char* scheme_name = nullptr/*return current scheme if was null*/); // call sane_config_schm::release() if not use anymore - sane_config_schm* create_empty_scheme(bool selected); // create an empty scheme and add to scheme queue - std::string get_current_scheme_name(void); - std::string to_text_stream(void); - void set_default_value(int id, const char* name, const char* title, void* data, size_t bytes, int type); - int option_value_type(const char* name); - std::string option_title(const char* name); - bool remove_scheme(const char* scheme_name); - void remove_all_schemes(void); - bool select_scheme(const char* scheme_name); - - sane_config_schm* copy_scheme(const char* cp_from_name); // for UI setting, call release() if not use anymore - bool add_scheme(sane_config_schm* schm, const char* name = nullptr, bool should_rename = false); - bool rename_scheme(const char* from, const char* to); - }; -}; diff --git a/sane/huagaotwain.cpp b/sane/huagaotwain.cpp deleted file mode 100644 index 7dda641..0000000 --- a/sane/huagaotwain.cpp +++ /dev/null @@ -1,2195 +0,0 @@ -#include "pch.h" -#include "huagaotwain.h" -#include "huagao/hgscanner_error.h" - -#define STR(s) #s -#define PASTE_STR(a, b) STR(a##b) -#define SANE_API(api) PASTE_STR(sane_hgsane_, api) -#define API_ELEM(api) {SANE_API(api), (FARPROC*)&real_sane_##api##_} -#ifdef VLOG_OK -#define vlog_debug_info sane_invoker::log_debug_info -#else -#define vlog_debug_info -#endif - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// utilities ... -namespace local_utility -{ - std::wstring reg_read(HKEY root, const wchar_t* path, const wchar_t* name) - { - HKEY key = NULL; - - RegOpenKeyW(root, path, &key); - if (!key) - return L""; - - wchar_t* buf = NULL; - DWORD len = 0; - DWORD type = REG_SZ; - std::wstring ret(L""); - - RegQueryValueExW(key, name, NULL, &type, (LPBYTE)buf, &len); - if(len) - { - buf = new wchar_t[len + 4]; - memset(buf, 0, (len + 4) * sizeof(*buf)); - RegQueryValueExW(key, name, NULL, &type, (LPBYTE)buf, &len); - ret = buf; - delete[] buf; - } - RegCloseKey(key); - - return ret; - } - std::wstring reg_get_app_installing_path(void) - { -#ifdef OEM_HANWANG - std::wstring path(L"SOFTWARE\\HwScanner"); -#elif defined(OEM_LISICHENG) - std::wstring path(L"SOFTWARE\\LscScanner"); -#else - std::wstring path(L"SOFTWARE\\HuaGoScan"); -#endif - - return reg_read(HKEY_LOCAL_MACHINE, path.c_str(), L"AppDirectory"); - } -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// scanned image ... -scanned_img::scanned_img(SANE_Image* img, SANE_FinalImgFormat* header) : param_(img->header) -{ - // PBITMAPINFOHEADER - size_t bytes = line_bytes() * height(); - std::string h(file_header(header, bytes)); - unsigned char *src = img->data + img->bytes - param_.bytes_per_line, - *dst = NULL; - - data_.resize(bytes + h.length()); - memcpy(&data_[0], h.c_str(), h.length()); - dst = (unsigned char*)&data_[0] + h.length(); - - if (param_.format == SANE_FRAME_RGB) - { - for (int i = 0; i < height(); ++i) - { - for (int j = 0; j < param_.pixels_per_line; ++j) - { - dst[j * 3 + 0] = src[j * 3 + 2]; - dst[j * 3 + 1] = src[j * 3 + 1]; - dst[j * 3 + 2] = src[j * 3 + 0]; - } - src -= param_.bytes_per_line; - dst += line_bytes(); - } - } - else - { - for (int i = 0; i < height(); ++i, dst += line_bytes(), src -= param_.bytes_per_line) - memcpy(dst, src, param_.bytes_per_line); - } -} -scanned_img::~scanned_img() -{} - -std::string scanned_img::file_header(SANE_FinalImgFormat* header, float resolution) -{ - std::string h(""); - - if (header->img_format == SANE_IMAGE_TYPE_BMP) - { - BITMAPINFOHEADER bih = { 0 }; - - bih.biSize = sizeof(bih); - bih.biWidth = width(); - bih.biBitCount = depth(); - bih.biSizeImage = line_bytes() * height(); - bih.biPlanes = 1; - bih.biHeight = height(); - bih.biCompression = BI_RGB; - bih.biXPelsPerMeter = bih.biYPelsPerMeter = resolution * 39.37f + .5f; - - h = std::string((char*)&bih, sizeof(bih)); - } - - return h; -} - -int scanned_img::width(void) -{ - return param_.pixels_per_line; -} -int scanned_img::line_bytes(void) -{ - return (param_.bytes_per_line + 3) / 4 * 4; -} -int scanned_img::height(void) -{ - return param_.lines; -} -int scanned_img::depth(void) -{ - if (param_.format == SANE_FRAME_RGB) - return param_.depth * 3; - else - return param_.depth; -} -int scanned_img::channel(void) -{ - return param_.format == SANE_FRAME_RGB ? 3 : 1; -} -SANE_Frame scanned_img::type(void) -{ - return param_.format; -} -unsigned int scanned_img::bytes(void) -{ - return data_.size(); -} -unsigned char* scanned_img::bits(void) -{ - return &data_[0]; -} -void scanned_img::copy_header(SANE_Parameters* head) -{ - *head = param_; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// sane_invoker ... - -sane_invoker* sane_invoker::inst_ = NULL; -sane_invoker::sane_invoker(const wchar_t* path) : ok_(false), ver_(0), sane_(NULL), first_cb_(NULL) -{ - memset(&sane_api_, 0, sizeof(sane_api_)); - cfg_file_ = std::wstring(path) + L"config.txt"; - if (load_sane()) - { - first_cb_ = CreateEventA(NULL, FALSE, FALSE, NULL); - real_sane_init_ex_(&ver_, &sane_invoker::sane_callback_handler, this); - - char msg[128] = { 0 }; - sprintf_s(msg, _countof(msg) - 1, "Wait sane first callback = %d\r\n", WaitForSingleObject(first_cb_, 1000)); - sane_invoker::log_debug_info(msg); - } -} -sane_invoker::~sane_invoker() -{ - if (sane_) - { - if(real_sane_exit_) - real_sane_exit_(); - FreeLibrary(sane_); - sane_ = NULL; - } - if (first_cb_) - CloseHandle(first_cb_); -} - -bool sane_invoker::load_sane() -{ - //sane_hgsane_init - //sane_hgsane_exit - //sane_hgsane_get_devices - //sane_hgsane_open - //sane_hgsane_close - //sane_hgsane_get_option_descriptor - //sane_hgsane_control_option - //sane_hgsane_get_parameters - //sane_hgsane_start - //sane_hgsane_read - //sane_hgsane_cancel - //sane_hgsane_set_io_mode - //sane_hgsane_get_select_fd - //sane_hgsane_strstatus - //sane_hgsane_init_ex - //sane_hgsane_io_control - struct { - std::string name; - FARPROC* api; - }apis[] = { API_ELEM(init), - API_ELEM(exit), - API_ELEM(get_devices), - API_ELEM(open), - API_ELEM(close), - API_ELEM(get_option_descriptor), - API_ELEM(control_option), - API_ELEM(get_parameters), - API_ELEM(start), - API_ELEM(read), - API_ELEM(cancel), - API_ELEM(set_io_mode), - API_ELEM(get_select_fd), - API_ELEM(strstatus), - API_ELEM(io_control), - API_ELEM(init_ex) - }; - - wchar_t sane_path[MAX_PATH] = { 0 }; - DWORD size = _countof(sane_path); - - log_ = &sane_invoker::no_log; - for (int i = 0; i < _countof(apis); ++i) - *apis[i].api = NULL; - - ok_ = false; -#ifdef USE_LOCAL_CONFIG - if (GetPrivateProfileStringW(L"sane", L"pe", L"", sane_path, size - 1, cfg_file_.c_str())) -#else - std::wstring reg(local_utility::reg_get_app_installing_path()); - wcscpy_s(sane_path, size - 1, reg.c_str()); - if(reg.length()) -#endif - { - wcscat(sane_path, L"\\hgsane.dll"); - size = sane_invoker::load_dll(sane_path, &sane_); - if (sane_) - { - ok_ = true; - *((FARPROC*)&log_) = GetProcAddress(sane_, "hg_debug_log"); - if (!log_) - log_ = &sane_invoker::no_log; - for (int i = 0; i < _countof(apis); ++i) - { - *apis[i].api = GetProcAddress(sane_, apis[i].name.c_str()); - if (!(*apis[i].api)) - { - vlog_debug_info(1024, "GetProcAddress(\"sane.dll\", \"%s\") failed with error: %d\r\n", apis[i].name.c_str(), GetLastError()); - ok_ = false; - } - } - if (ok_) - { - vlog_debug_info(1024, "sane component load success, path = \"%s\"\r\n", sane_invoker::u2ansi(sane_path).c_str()); - for (int i = 0; i < sizeof(sane_api_) / sizeof(sane_api_.sane_cancel_api); ++i) - ((FARPROC*)&sane_api_)[i] = *apis[i + 2].api; - } - } - else - { - vlog_debug_info(1024, "LoadLibraryW(\"%s\") failed with error: %d\r\n", sane_invoker::u2ansi(sane_path).c_str(), GetLastError()); - } - } - else - { - vlog_debug_info(1024, "GetPrivateProfileStringW(\"sane\", \"pe\", \"%s\") failed\r\n", sane_invoker::u2ansi(cfg_file_.c_str()).c_str()); - } - - return ok_; -} -int sane_invoker::handle_sane_event(SANE_Handle hdev, int code, void* data, unsigned int* len) -{ - SetEvent(first_cb_); - if (code == SANE_EVENT_DEVICE_ARRIVED) - { - SANE_Device* sdev = (SANE_Device*)data; - SANEDEV dev; - std::lock_guard lock(lock_dev_); - std::vector::iterator it = std::find(devices_.begin(), devices_.end(), sdev->name); - - if (it == devices_.end()) - { - dev.name = sdev->name; - dev.type = sdev->model; - dev.product = sdev->type; - dev.vendor = sdev->vendor; - devices_.push_back(dev); - } - else if (it->scanner) - it->scanner->set_online(true); - } - else if (code == SANE_EVENT_DEVICE_LEFT) - { - SANE_Device* sdev = (SANE_Device*)data; - std::lock_guard lock(lock_dev_); - std::vector::iterator it = std::find(devices_.begin(), devices_.end(), sdev->name); - if (it != devices_.end()) - { - if (it->scanner) - it->scanner->set_online(false); - else - devices_.erase(it); - } - } - else if (code == SANE_EVENT_IMAGE_OK) - { - scanner* dev = find_scanner(hdev); - if (dev) - { - dev->put_image((SANE_Image*)data, len); - dev->release(); - } - } - else if (code == SANE_EVENT_SCAN_FINISHED) - { - scanner* dev = find_scanner(hdev); - if (dev) - { - dev->scan_finished((char*)data, *len); - } - } - else if (code == SANE_EVENT_ERROR) - { - std::wstring msg(sane_invoker::utf82u((char*)data)); - MessageBoxW(NULL, msg.c_str(), L"Error", MB_OK); - } - - return SCANNER_ERR_OK; -} -void sane_invoker::get_online_devices(std::vector& devs) -{ - std::lock_guard lock(lock_dev_); - - devs = devices_; -} -int sane_invoker::get_online_device_count(void) -{ - std::lock_guard lock(lock_dev_); - - return devices_.size(); -} -scanner* sane_invoker::find_scanner(SANE_Handle hdev) -{ - std::lock_guard lock(lock_dev_); - std::vector::iterator it = std::find(devices_.begin(), devices_.end(), hdev); - - if (it == devices_.end()) - return NULL; - else - { - it->scanner->add_ref(); - - return it->scanner; - } -} -scanner* sane_invoker::open(const char* name, int* err) -{ - std::lock_guard lock(lock_dev_); - std::vector::iterator it = std::find(devices_.begin(), devices_.end(), name); - - if (it == devices_.end()) - { - if (err) - *err = SCANNER_ERR_DEVICE_NOT_FOUND; - - return NULL; - } - - scanner *s = new scanner(this, *it); - if (s->last_error() != SANE_STATUS_GOOD) - { - if (err) - *err = s->last_error(); - s->release(); - s = NULL; - } - - return s; -} - -void sane_invoker::no_log(int, const char* info) -{ - OutputDebugStringA(info); -} -int sane_invoker::sane_callback_handler(SANE_Handle hdev, int code, void* data, unsigned int* len, void* param) -{ - return ((sane_invoker*)param)->handle_sane_event(hdev, code, data, len); -} - -int sane_invoker::load_dll(const wchar_t* path_dll, HMODULE* dll) -{ - HMODULE h = LoadLibraryW(path_dll); - int ret = 0; - - if (!h && GetLastError() == ERROR_MOD_NOT_FOUND) - { - std::wstring dir(path_dll); - size_t pos = dir.rfind(L'\\'); - wchar_t path[MAX_PATH] = { 0 }; - - GetCurrentDirectoryW(_countof(path) - 1, path); - if (pos != std::wstring::npos) - dir.erase(pos); - SetCurrentDirectoryW(dir.c_str()); - h = LoadLibraryW(path_dll); - ret = GetLastError(); - SetCurrentDirectoryW(path); - } - else - ret = GetLastError(); - - if (dll) - *dll = h; - - return ret; -} -bool sane_invoker::initialize(HMODULE me) -{ - if (sane_invoker::inst_) - return false; - else - { - wchar_t path[MAX_PATH] = { 0 }, * last = NULL; - - GetModuleFileNameW(me, path, _countof(path) - 1); - last = wcsrchr(path, L'\\'); - if (last++) - *last = 0; - sane_invoker::inst_ = new sane_invoker(path); - - return true; - } -} -void sane_invoker::uninitialize(void) -{ - if (sane_invoker::inst_) - delete sane_invoker::inst_; - sane_invoker::inst_ = NULL; -} -std::string sane_invoker::u2m(const wchar_t* u, int page) -{ - char *ansi = NULL; - int len = 0; - std::string mb(""); - - len = WideCharToMultiByte(page, 0, u, lstrlenW(u), NULL, 0, NULL, NULL); - ansi = new char[len + 2]; - len = WideCharToMultiByte(page, 0, u, lstrlenW(u), ansi, len, NULL, NULL); - ansi[len--] = 0; - mb = ansi; - delete[] ansi; - - return mb; -} -std::wstring sane_invoker::m2u(const char* m, int page) -{ - wchar_t *unic = NULL; - int len = 0; - std::wstring u(L""); - - len = MultiByteToWideChar(page, 0, m, lstrlenA(m), NULL, 0); - unic = new wchar_t[len + 2]; - len = MultiByteToWideChar(page, 0, m, lstrlenA(m), unic, len); - unic[len--] = 0; - u = unic; - delete[] unic; - - return u; -} -std::string sane_invoker::u2ansi(const wchar_t* u) -{ - return sane_invoker::u2m(u, CP_ACP); -} -std::string sane_invoker::u2utf8(const wchar_t* u) -{ - return sane_invoker::u2m(u, CP_UTF8); -} -std::string sane_invoker::utf82ansi(const char* utf8) -{ - return sane_invoker::u2m(sane_invoker::m2u(utf8, CP_UTF8).c_str(), CP_ACP); -} -std::string sane_invoker::ansi2utf8(const char* ansi) -{ - return sane_invoker::u2m(sane_invoker::m2u(ansi, CP_ACP).c_str(), CP_UTF8); -} -std::wstring sane_invoker::utf82u(const char* utf8) -{ - return sane_invoker::m2u(utf8, CP_UTF8); -} -std::wstring sane_invoker::ansi2u(const char* ansi) -{ - return sane_invoker::m2u(ansi, CP_ACP); -} -void sane_invoker::log_debug_info(const char* info) -{ - if (sane_invoker::inst_) - sane_invoker::inst_->log_(/*LOG_LEVEL_DEBUG_INFO*/1, info); - else - OutputDebugStringA(info); -} -#ifdef VLOG_OK -void __cdecl sane_invoker::log_debug_info(int bytes, const char* fmt, ...) -{ - std::string str(bytes + 20, 0); - - va_list args; - - va_start(args, fmt); - sprintf_s(&str[0], bytes, fmt, args); - va_end(args); - - vlog_debug_info(str.c_str()); -} -#endif - -SANE_Status sane_invoker::invoke_sane_init(SANE_Int* version_code, SANE_Auth_Callback authorize) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_init_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_init_(version_code, authorize); -} -void sane_invoker::invoke_sane_exit(void) -{ - if (sane_invoker::inst_ && sane_invoker::inst_->real_sane_exit_) - sane_invoker::inst_->real_sane_exit_(); -} -SANE_Status sane_invoker::invoke_sane_get_devices(const SANE_Device*** device_list, SANE_Bool local_only) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_get_devices_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_get_devices_(device_list, local_only); -} -SANE_Status sane_invoker::invoke_sane_open(SANE_String_Const devicename, SANE_Handle* handle) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_open_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_open_(devicename, handle); -} -void sane_invoker::invoke_sane_close(SANE_Handle handle) -{ - if (sane_invoker::inst_ && sane_invoker::inst_->real_sane_close_) - sane_invoker::inst_->real_sane_close_(handle); -} -const SANE_Option_Descriptor* sane_invoker::invoke_sane_get_option_descriptor(SANE_Handle handle, SANE_Int option) -{ - if (!sane_invoker::inst_) - return NULL; - - if (!sane_invoker::inst_->real_sane_get_option_descriptor_) - return NULL; - - return sane_invoker::inst_->real_sane_get_option_descriptor_(handle, option); -} -SANE_Status sane_invoker::invoke_sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void* value, SANE_Int* info) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_control_option_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_control_option_(handle, option, action, value, info); -} -SANE_Status sane_invoker::invoke_sane_get_parameters(SANE_Handle handle, SANE_Parameters* params) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_get_parameters_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_get_parameters_(handle, params); -} -SANE_Status sane_invoker::invoke_sane_start(SANE_Handle handle) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_start_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_start_(handle); -} -SANE_Status sane_invoker::invoke_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_read_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_read_(handle, data, max_length, length); -} -void sane_invoker::invoke_sane_cancel(SANE_Handle handle) -{ - if (sane_invoker::inst_ && sane_invoker::inst_->real_sane_cancel_) - sane_invoker::inst_->invoke_sane_cancel(handle); -} -SANE_Status sane_invoker::invoke_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_set_io_mode_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_set_io_mode_(handle, non_blocking); -} -SANE_Status sane_invoker::invoke_sane_get_select_fd(SANE_Handle handle, SANE_Int* fd) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_get_select_fd_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_get_select_fd_(handle, fd); -} -SANE_String_Const sane_invoker::invoke_sane_strstatus(SANE_Status status) -{ - if (sane_invoker::inst_ && sane_invoker::inst_->real_sane_strstatus_) - return sane_invoker::inst_->real_sane_strstatus_(status); - else - return ""; -} -SANE_Status sane_invoker::invoke_sane_init_ex(SANE_Int* version_code, sane_callback cb, void* param) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_init_ex_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_init_ex_(version_code, cb, param); -} -SANE_Status sane_invoker::invoke_sane_io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len) -{ - if (!sane_invoker::inst_) - return (SANE_Status)SCANNER_ERR_NOT_OPEN; - - if (!sane_invoker::inst_->real_sane_io_control_) - return SANE_STATUS_UNSUPPORTED; - - return sane_invoker::inst_->real_sane_io_control_(h, code, data, len); -} - -LPSANEAPI sane_invoker::get_api(void) -{ - if (sane_invoker::inst_) - return &sane_invoker::inst_->sane_api_; - else - return NULL; -} - -bool sane_invoker::is_ok(void) -{ - if (sane_invoker::inst_) - return sane_invoker::inst_->ok_; - else - return false; -} -std::string sane_invoker::version(LPDWORD v) -{ - char vs[40] = { 0 }; - DWORD ver = 0; - - if (sane_invoker::inst_) - ver = sane_invoker::inst_->ver_; - - sprintf_s(vs, _countof(vs) - 1, "%u.%u.%u", (ver >> 24) & 0x0ff, (ver >> 16) & 0x0ff, ver & 0x0ffff); - if (v) - *v = ver; - - return vs; -} -void sane_invoker::get_devices(std::vector& devs) -{ - if (sane_invoker::inst_) - sane_invoker::inst_->get_online_devices(devs); -} -scanner* sane_invoker::open_scanner(const char* name, int* err) -{ - if (!sane_invoker::inst_) - { - if (err) - *err = SCANNER_ERR_NOT_OPEN; - - return NULL; - } - - return sane_invoker::inst_->open(name, err); -} -int sane_invoker::online_devices(void) -{ - if (sane_invoker::inst_) - sane_invoker::inst_->get_online_device_count(); - else - return 0; -} - - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// scanner ... -#define FIND_OPTION(opt) \ - std::vector::iterator it = std::find(options_.begin(), options_.end(), opt); - -scanner::scanner(sane_invoker* host, struct _dev& dev) : host_(host), hdev_(NULL), dpi_(200.0f), option_count_(0), event_cb_(NULL) - , name_(dev.name), type_(dev.type), vendor_(dev.vendor), product_(dev.product), cb_param_(NULL) - , scanning_(false), wait_img_(CreateEventA(NULL, TRUE, FALSE, NULL)), fmt_(NULL) - , opt_ind_dpi_(-1), opt_ind_color_mode_(-1), opt_ind_paper_(-1), opt_ind_scann_count_(-1) - , jpeg_quality_(80), opt_ind_text_direction_(-1), opt_ind_page_(-1), img_fmt_(SANE_IMAGE_TYPE_BMP) - , opt_ind_auto_descrew_(-1), opt_ind_erase_black_frame_(-1), opt_ind_filter_(-1), opt_ind_bright_(-1) - , opt_ind_contrast_(-1), opt_ind_gamma_(-1), opt_ind_ultrasonic_(-1), err_(SCANNER_ERR_OK), desc_("") - , compression_(SANE_COMPRESSION_NONE), opt_ind_flip_(-1), auto_crop_(false), opt_ind_rotate_bkg_(-1) - , opt_ind_fill_blank_bkg_(-1), opt_ind_edge_ident_(-1), opt_ind_threshold_(-1), opt_ind_bkg_filling_method_(-1) - , opt_ind_fill_hole_(-1), opt_ind_fill_hole_ratio_(-1), opt_ind_noise_(-1), opt_ind_noise_threshold_(-1) - , opt_ind_rid_red_hsv_(-1), opt_ind_rid_red_(-1), opt_ind_sharpen_(-1), opt_ind_screw_detect_(-1), opt_ind_screw_detect_level_(-1) - , opt_ind_staple_(-1), opt_ind_dogear_(-1), opt_ind_dark_sample_(-1), opt_ind_split_(-1), opt_ind_fade_bkg_(-1) - , opt_ind_fade_bkg_val_(-1), opt_ind_size_detect_(-1), opt_ind_multi_out_(-1) -{ - dev.scanner = this; - - SANE_Status statu = sane_invoker::invoke_sane_open(name_.c_str(), &hdev_); - online_ = statu == SANE_STATUS_GOOD; - { - vlog_debug_info(128, "scanner(0x%x) generated, open '%s' = %d\r\n", this, name_.c_str(), statu); - } - if (online_) - load_options(); - init_image_format(); - err_ = statu; -} -scanner::~scanner() -{ - if (fmt_) - delete[](char*)fmt_; - for (auto& v : options_) - { - if (v.desc->type == SANE_Value_Type::SANE_TYPE_STRING) - delete v.val.sv; - } - - vlog_debug_info(128, "scanner(0x%x) destroyed\r\n", this); -} - -std::string scanner::type(SANE_Value_Type st) -{ - switch (st) - { - case SANE_Value_Type::SANE_TYPE_BOOL: - return "bool"; - case SANE_Value_Type::SANE_TYPE_BUTTON: - return "button"; - case SANE_Value_Type::SANE_TYPE_FIXED: - return "float"; - case SANE_Value_Type::SANE_TYPE_INT: - return "int"; - case SANE_Value_Type::SANE_TYPE_STRING: - return "string"; - default: - return ""; - } -} -value_limit scanner::limit(SANE_Constraint_Type st) -{ - switch (st) - { - case SANE_Constraint_Type::SANE_CONSTRAINT_RANGE: - return VAL_LIMIT_RANGE; - case SANE_Constraint_Type::SANE_CONSTRAINT_STRING_LIST: - case SANE_Constraint_Type::SANE_CONSTRAINT_WORD_LIST: - return VAL_LIMIT_ENUM; - default: - return VAL_LIMIT_NONE; - } -} - -void scanner::load_options(void) -{ - SANE_Int count = 0, afterdo = 0; - SANE_Status statu = sane_invoker::invoke_sane_control_option(hdev_, 0, SANE_ACTION_GET_VALUE, &count, &afterdo); - - option_count_ = 0; - if (statu != SANE_STATUS_GOOD) - { - vlog_debug_info(128, "get option count failed with error: %d\r\n", statu); - return; - } - else - vlog_debug_info(128, "\"%s\" has %d options.\r\n", count); - - option_count_ = count; - for (int i = 1; i < option_count_; ++i) - { - const SANE_Option_Descriptor* desc = sane_invoker::invoke_sane_get_option_descriptor(hdev_, i); - SANEOPTION op; - - op.ind = i; - op.desc = desc; - if (desc->type == SANE_Value_Type::SANE_TYPE_BOOL) - op.val.bv = get_boolean(i); - else if (desc->type == SANE_Value_Type::SANE_TYPE_FIXED) - op.val.dv = get_double(i); - else if (desc->type == SANE_Value_Type::SANE_TYPE_INT) - op.val.iv = get_integer(i); - else if (desc->type == SANE_Value_Type::SANE_TYPE_STRING) - op.val.sv = new std::string(get_string(i, desc->size)); - options_.push_back(op); - if (color_mode::is_me(desc->title)) - opt_ind_color_mode_ = i; - else if (dpi::is_me(desc->title)) - opt_ind_dpi_ = i; - else if (paper::is_me(desc->title)) - opt_ind_paper_ = i; - else if (scan_count::is_me(desc->title)) - opt_ind_scann_count_ = MAKELPARAM(i, HIWORD(opt_ind_scann_count_)); - else if (scan_count::is_parent(desc->title)) - opt_ind_scann_count_ = MAKELPARAM(LOWORD(opt_ind_scann_count_), i); - else if (text_direction::is_me(desc->title)) - opt_ind_text_direction_ = i; - else if (page::is_me(desc->title)) - opt_ind_page_ = i; - else if (auto_descrew::is_me(desc->title)) - opt_ind_auto_descrew_ = i; - else if (erase_black_frame::is_me(desc->title)) - opt_ind_erase_black_frame_ = i; - else if (filter::is_me(desc->title)) - opt_ind_filter_ = i; - else if (bright::is_me(desc->title)) - opt_ind_bright_ = i; - else if (contrast::is_me(desc->title)) - opt_ind_contrast_ = i; - else if (gamma::is_me(desc->title)) - opt_ind_gamma_ = i; - else if (ultrasonic::is_me(desc->title)) - opt_ind_ultrasonic_ = i; - else if (flip::is_me(desc->title)) - opt_ind_flip_ = i; - else if (rotate_bg::is_me(desc->title)) - opt_ind_rotate_bkg_ = i; - else if (fill_black_border::is_me(desc->title)) - opt_ind_fill_blank_bkg_ = i; - else if (edge_ident::is_me(desc->title)) - opt_ind_edge_ident_ = i; - else if (threshold::is_me(desc->title)) - opt_ind_threshold_ = i; - else if (bkg_filling_method::is_me(desc->title)) - opt_ind_bkg_filling_method_ = i; - else if (fill_hole::is_me(desc->title)) - opt_ind_fill_hole_ = i; - else if (fill_hole::is_ratio(desc->title)) - opt_ind_fill_hole_ratio_ = i; - else if (noise::is_me(desc->title)) - opt_ind_noise_ = i; - else if (noise::is_threshold(desc->title)) - opt_ind_noise_threshold_ = i; - else if (rid_red::is_me(desc->title, false)) - opt_ind_rid_red_ = i; - else if (rid_red::is_me(desc->title, true)) - opt_ind_rid_red_hsv_ = i; - else if (sharpen::is_me(desc->title)) - opt_ind_sharpen_ = i; - else if (screw::is_me(desc->title)) - opt_ind_screw_detect_ = i; - else if (screw::is_level(desc->title)) - opt_ind_screw_detect_level_ = i; - else if (staple::is_me(desc->title)) - opt_ind_staple_ = i; - else if (dogear::is_me(desc->title)) - opt_ind_dogear_ = i; - else if (sample::is_me(desc->title)) - opt_ind_dark_sample_ = i; - else if (split::is_me(desc->title)) - opt_ind_split_ = i; - else if (fade_bkg::is_me(desc->title)) - opt_ind_fade_bkg_ = i; - else if (fade_bkg::is_value(desc->title)) - opt_ind_fade_bkg_val_ = i; - else if (size_detect::is_me(desc->title)) - opt_ind_size_detect_ = i; - else if (multi_out::is_me(desc->title)) - opt_ind_multi_out_ = i; - } -} -void scanner::init_image_format(void) -{ - if (fmt_) - delete[](char*)fmt_; - - int len = sizeof(SANE_FinalImgFormat) + sizeof(BITMAPINFOHEADER); - PBITMAPINFOHEADER pbi = NULL; - - fmt_ = (SANE_FinalImgFormat*)new char[len]; - memset(fmt_, 0, len); - fmt_->img_format = SANE_IMAGE_TYPE_BMP; - pbi = (PBITMAPINFOHEADER)fmt_->detail; -} -std::string scanner::get_string(int opt, int bytes) -{ - std::string ret(""); - char* v = new char[bytes + 4]; - SANE_Int afterdo = 0; - - memset(v, 0, bytes + 4); - sane_invoker::invoke_sane_control_option(hdev_, opt, SANE_ACTION_GET_VALUE, v, &afterdo); - ret = v; - delete[] v; - - return ret; -} -bool scanner::get_boolean(int opt) -{ - SANE_Int afterdo = 0; - SANE_Bool v = 0; - - sane_invoker::invoke_sane_control_option(hdev_, opt, SANE_ACTION_GET_VALUE, &v, &afterdo); - - return v; -} -int scanner::get_integer(int opt) -{ - SANE_Int afterdo = 0; - SANE_Int v = 0; - - sane_invoker::invoke_sane_control_option(hdev_, opt, SANE_ACTION_GET_VALUE, &v, &afterdo); - - return v; -} -double scanner::get_double(int opt) -{ - SANE_Int afterdo = 0; - SANE_Fixed f = 0; - - sane_invoker::invoke_sane_control_option(hdev_, opt, SANE_ACTION_GET_VALUE, &f, &afterdo); - - return SANE_UNFIX(f); -} -int scanner::set_string(int opt, std::string& val, int size, SANE_Int* afterdo) -{ - SANE_Int after = 0; - char* buf = new char[size + 20]; - int ret = 0; - - memset(buf, 0, size + 20); - strcpy(buf, val.c_str()); - ret = sane_invoker::invoke_sane_control_option(hdev_, opt, SANE_ACTION_SET_VALUE, buf, &after); - val = buf; - delete[] buf; - if (afterdo) - *afterdo = after; - - return ret; -} - -int scanner::close(void) -{ - if (hdev_) - { - sane_invoker::invoke_sane_close(hdev_); - hdev_ = NULL; - } - - return SCANNER_ERR_OK; -} -int scanner::start(void) -{ - int ret = SCANNER_ERR_NOT_OPEN; - - ResetEvent(wait_img_); - if (hdev_) - ret = sane_invoker::invoke_sane_start(hdev_); - scanning_ = ret == SANE_STATUS_GOOD; - - return ret; -} -int scanner::stop(void) -{ - scanning_ = false; - if (hdev_) - sane_invoker::invoke_sane_cancel(hdev_); - - return SCANNER_ERR_OK; -} -void scanner::set_event_callback(void(*cb)(int, void*, unsigned int*, void*), void* param) -{ - cb_param_ = param; - event_cb_ = cb; -} -bool scanner::wait_image(DWORD milliseconds) -{ - { - std::lock_guard lock(lock_img_); - if (img_.size()) - return true; - } - - if (!scanning_) - { - if (err_) - { - std::wstring tips(sane_invoker::utf82u(desc_.c_str())); - MessageBoxW(NULL, tips.c_str(), L"\u9519\u8bef", MB_OK); - } - return false; - } - - WaitForSingleObject(wait_img_, milliseconds); - - return img_.size() > 0; -} -int scanner::get_scanned_images(DWORD milliseconds) -{ - if (milliseconds && !wait_image(milliseconds)) - return 0; - else - { - std::lock_guard lock(lock_img_); - - return img_.size(); - } -} -scanned_img* scanner::take_first_image(void) // delete returned value, plz -{ - std::lock_guard lock(lock_img_); - scanned_img* img = NULL; - - if (img_.size()) - { - img = img_[0]; - img_.erase(img_.begin()); - ResetEvent(wait_img_); - } - - return img; -} -bool scanner::get_first_image_header(SANE_Parameters* header) -{ - std::lock_guard lock(lock_img_); - if (img_.size()) - { - img_[0]->copy_header(header); - header->bytes_per_line = img_[0]->line_bytes(); - if (header->format == SANE_FRAME_RGB) - header->depth *= 3; - - return true; - } - - return false; -} -int scanner::last_error(void) -{ - return err_; -} - -SANE_Handle scanner::handle(void) -{ - return hdev_; -} -bool scanner::is_online(void) -{ - return online_; -} -void scanner::set_online(bool online) -{ - online_ = online; -} - - -void scanner::put_image(SANE_Image* img, unsigned int* len) -{ - std::lock_guard lock(lock_img_); - img_.push_back(new scanned_img(img, fmt_)); - SetEvent(wait_img_); - if (event_cb_) - event_cb_(SANE_EVENT_IMAGE_OK, (void*)img, len, cb_param_); -} -void scanner::scan_finished(const char* desc, int err) -{ - desc_ = desc ? desc : "OK"; - err_ = err; - scanning_ = false; - SetEvent(wait_img_); - if (event_cb_) - event_cb_(SANE_EVENT_SCAN_FINISHED, (void*)desc, (unsigned int*)&err, cb_param_); -} - -// up to sane, we set the CAP_xxx according to settings display in UI ... -bool scanner::get_value_info(int sn, std::string& type, value_limit& limit) -{ - if (sn <= 0 || sn >= option_count_) - return false; - - FIND_OPTION(sn); - if (it == options_.end()) - return false; - - type = scanner::type(it->desc->type); - limit = scanner::limit(it->desc->constraint_type); - - return true; -} -bool scanner::get_value(int sn, std::list& values, std::string& now, std::string& init) -{ - if (sn <= 0 || sn >= option_count_) - return false; - - FIND_OPTION(sn); - if (it == options_.end()) - return false; - - if (scanner::type(it->desc->type) != "string" || - scanner::limit(it->desc->constraint_type) != VAL_LIMIT_ENUM) - return false; - - sane_trans::get_value_list(it->desc, &values); - init = *it->val.sv; - now = get_string(sn, it->desc->size); - - return true; -} -bool scanner::get_value(int sn, std::list& values, float& now, float& init) -{ - if (sn <= 0 || sn >= option_count_) - return false; - - FIND_OPTION(sn); - if (it == options_.end()) - return false; - - if (scanner::type(it->desc->type) != "float" || - scanner::limit(it->desc->constraint_type) != VAL_LIMIT_ENUM) - return false; - - std::list vals; - sane_trans::get_value_list(it->desc, &vals); - for(const auto& v : vals) - values.push_back(v); - - init = it->val.dv; - now = get_double(sn); - - return true; -} -bool scanner::get_value(int sn, std::list& values, bool& now, bool& init) -{ - if (sn <= 0 || sn >= option_count_) - return false; - - FIND_OPTION(sn); - if (it == options_.end()) - return false; - - values.push_back(false); - values.push_back(true); - now = get_boolean(sn); - init = it->val.bv; - - return true; -} -bool scanner::get_value(int sn, int& now, int& init, int* lower, int* upper, int* step) -{ - if (sn <= 0 || sn >= option_count_) - return false; - - FIND_OPTION(sn); - if (it == options_.end()) - return false; - - if (scanner::type(it->desc->type) != "int") - return false; - - bool ret = true; - now = get_integer(sn); - init = it->val.iv; - if (lower && upper && step) - { - *lower = *upper = *step = 0; - if (scanner::limit(it->desc->constraint_type) == VAL_LIMIT_RANGE) - { - *lower = it->desc->constraint.range->min; - *upper = it->desc->constraint.range->max; - *step = it->desc->constraint.range->quant; - } - else - ret = false; - } - - return ret; -} -bool scanner::get_value(int sn, float& now, float& init, float* lower, float* upper, float* step) -{ - if (sn <= 0 || sn >= option_count_) - return false; - - std::vector::iterator it = std::find(options_.begin(), options_.end(), sn); - if (it == options_.end()) - return false; - - if (scanner::type(it->desc->type) != "float") - return false; - - bool ret = true; - double ratio = sn == opt_ind_fill_hole_ratio_ ? 100.0f : 1.0f; - now = get_double(sn) * ratio; - init = it->val.dv * ratio; - if (lower && upper && step) - { - *lower = *upper = *step = 0; - if (scanner::limit(it->desc->constraint_type) == VAL_LIMIT_RANGE) - { - *lower = SANE_UNFIX(it->desc->constraint.range->min) * ratio; - *upper = SANE_UNFIX(it->desc->constraint.range->max) * ratio; - *step = SANE_UNFIX(it->desc->constraint.range->quant) * ratio; - } - else - ret = false; - } - - return ret; -} - -int scanner::set_value(int sn, std::string val) -{ - if (sn <= 0 || sn >= option_count_) - return SCANNER_ERR_OUT_OF_RANGE; - - std::vector::iterator it = std::find(options_.begin(), options_.end(), sn); - if (it == options_.end()) - return SCANNER_ERR_NO_DATA; - - if (scanner::type(it->desc->type) != "string" || - val.length() > it->desc->size) - return SCANNER_ERR_INVALID_PARAMETER; - - char* buf = new char[it->desc->size + 20]; - int ret = SCANNER_ERR_OK; - SANE_Int afterdo = 0; - - memset(buf, 0, it->desc->size + 20); - strcpy(buf, val.c_str()); - ret = sane_invoker::invoke_sane_control_option(hdev_, sn, SANE_ACTION_SET_VALUE, buf, &afterdo); - if (sn == opt_ind_paper_ && (ret == SCANNER_ERR_OK || ret == SCANNER_ERR_NOT_EXACT)) - { - auto_crop_ = paper::is_auto_crop(buf); - } - delete[] buf; - - return ret; -} -int scanner::set_value(int sn, bool val) -{ - if (sn <= 0 || sn >= option_count_) - return SCANNER_ERR_OUT_OF_RANGE; - - std::vector::iterator it = std::find(options_.begin(), options_.end(), sn); - if (it == options_.end()) - return SCANNER_ERR_NO_DATA; - - if (scanner::type(it->desc->type) != "bool" && - scanner::type(it->desc->type) != "button") - return SCANNER_ERR_INVALID_PARAMETER; - - int ret = SCANNER_ERR_OK; - SANE_Int afterdo = 0; - SANE_Bool v = val; - - ret = sane_invoker::invoke_sane_control_option(hdev_, sn, SANE_ACTION_SET_VALUE, &v, &afterdo); - - return ret; -} -int scanner::set_value(int sn, int val) -{ - if (sn <= 0 || sn >= option_count_) - return SCANNER_ERR_OUT_OF_RANGE; - - std::vector::iterator it = std::find(options_.begin(), options_.end(), sn); - if (it == options_.end()) - return SCANNER_ERR_NO_DATA; - - if (scanner::type(it->desc->type) != "int") - return SCANNER_ERR_INVALID_PARAMETER; - - int ret = SCANNER_ERR_OK; - SANE_Int afterdo = 0; - SANE_Int v = val; - - ret = sane_invoker::invoke_sane_control_option(hdev_, sn, SANE_ACTION_SET_VALUE, &v, &afterdo); - - return ret; -} -int scanner::set_value(int sn, double val) -{ - if (sn <= 0 || sn >= option_count_) - return SCANNER_ERR_OUT_OF_RANGE; - - std::vector::iterator it = std::find(options_.begin(), options_.end(), sn); - if (it == options_.end()) - return SCANNER_ERR_NO_DATA; - - if (scanner::type(it->desc->type) != "float") - return SCANNER_ERR_INVALID_PARAMETER; - - if (sn == opt_ind_fill_hole_ratio_) - val /= 100.0f; - - int ret = SCANNER_ERR_OK; - SANE_Int afterdo = 0; - SANE_Fixed v = SANE_FIX(val); - - ret = sane_invoker::invoke_sane_control_option(hdev_, sn, SANE_ACTION_SET_VALUE, &v, &afterdo); - - return ret; -} - -int scanner::twain_set_resolution(float dpi) -{ - float l = .0f, u = .0f, n = .0f, i = .0f; - - if(opt_ind_dpi_ == -1 || - !get_value(opt_ind_dpi_, n, i, &l, &u)) - return dpi >= 200.0f && dpi <= 600.0f ? SCANNER_ERR_OK : SCANNER_ERR_INVALID_PARAMETER; - - if (dpi <= l || dpi >= u) - return SCANNER_ERR_INVALID_PARAMETER; - - std::vector::iterator it = std::find(options_.begin(), options_.end(), opt_ind_dpi_); - SANE_Fixed v = it->desc->type == SANE_TYPE_FIXED ? SANE_FIX(dpi) : dpi; - SANE_Int afterdo = 0; - int ret = sane_invoker::invoke_sane_control_option(hdev_, opt_ind_dpi_, SANE_ACTION_SET_VALUE, &v, &afterdo); - - dpi_ = it->desc->type == SANE_TYPE_FIXED ? SANE_UNFIX(v) : v; - - return ret; -} -float scanner::twain_get_resolution(float* init, std::vector* values, value_limit* limit) -{ - if (opt_ind_dpi_ != -1) - { - std::vector< SANEOPTION>::iterator it = std::find(options_.begin(), options_.end(), opt_ind_dpi_); - if (it != options_.end()) - { - if(init) - *init = it->val.dv; - - if (limit) - *limit = scanner::limit(it->desc->constraint_type); - if (values && (it->desc->type == SANE_TYPE_FIXED || it->desc->type == SANE_TYPE_INT)) - { - if (it->desc->constraint_type == SANE_CONSTRAINT_WORD_LIST) - { - const SANE_Word* val = it->desc->constraint.word_list; - for (SANE_Word i = 1; i < val[0]; ++i) - values->push_back(it->desc->type == SANE_TYPE_FIXED ? SANE_UNFIX(val[i]) : val[i]); - } - else if (it->desc->constraint_type == SANE_CONSTRAINT_RANGE) - { - const SANE_Range* r = it->desc->constraint.range; - values->push_back(it->desc->type == SANE_TYPE_FIXED ? SANE_UNFIX(r->min) : r->min); - values->push_back(it->desc->type == SANE_TYPE_FIXED ? SANE_UNFIX(r->max) : r->max); - } - } - } - } - if (values && values->empty()) - { - values->push_back(100.0f); - values->push_back(600.0f); - if (limit) - *limit = VAL_LIMIT_RANGE; - } - - return dpi_; -} - -int scanner::twain_set_color_mode(int twain_pixel_type) -{ - int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - - for (const auto& v : options_) - { - if (v.ind != opt_ind_color_mode_) - continue; - - std::string val(color_mode::from_twain_pixel_type(twain_pixel_type)); - char* buf = new char[v.desc->size + 8]; - SANE_Int afterdo = 0; - - memset(buf, 0, v.desc->size + 8); - strcpy(buf, val.c_str()); - ret = sane_invoker::invoke_sane_control_option(hdev_, v.ind, SANE_ACTION_SET_VALUE, buf, &afterdo); - delete buf; - break; - } - - return SCANNER_ERR_OK; -} -int scanner::twain_get_color_mode(int* init, std::vector* values, value_limit* limit) -{ - int tw_pixel_type = TWPT_RGB; - - for(const auto& v : options_) - { - if (v.ind != opt_ind_color_mode_) - continue; - - if (v.desc->type == SANE_Value_Type::SANE_TYPE_STRING) - { - SANE_Int afterdo = 0; - char* now = new char[v.desc->size + 8]; - - memset(now, 0, v.desc->size + 8); - sane_invoker::invoke_sane_control_option(hdev_, v.ind, SANE_ACTION_GET_VALUE, now, &afterdo); - tw_pixel_type = color_mode::to_twain_pixel_type(now); - if (init) - *init = color_mode::to_twain_pixel_type(v.val.sv->c_str()); - if (values && limit) - { - std::list vals; - if (sane_trans::get_value_list(v.desc, &vals)) - { - *limit = VAL_LIMIT_ENUM; - for (const auto& var : vals) - values->push_back(color_mode::to_twain_pixel_type(var.c_str())); - } - } - - delete[] now; - } - break; - } - - if (values && values->empty()) - { - values->push_back(TWPT_BW); - values->push_back(TWPT_GRAY); - values->push_back(TWPT_RGB); - if (limit) - *limit = VAL_LIMIT_ENUM; - } - return tw_pixel_type; -} -int scanner::twain_set_auto_color_type(int type) -{ - unsigned int len = sizeof(type); - - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_SET_AUTO_COLOR_TYPE, &type, &len); -} - -int scanner::twain_get_paper_ind(void) -{ - return opt_ind_paper_; -} -int scanner::twain_set_paper_lateral(bool lateral) -{ - FIND_OPTION(opt_ind_paper_); - if (it == options_.end()) - return SCANNER_ERR_INVALID_PARAMETER; - - std::list vals; - std::string now(get_string(opt_ind_paper_, it->desc->size)); - size_t pos = now.find(paper::lateral_title()); - int ret = SCANNER_ERR_OK; - - if (lateral) - { - if (!paper::is_lateral(now.c_str())) - { - now += paper::lateral_title(); - sane_trans::get_value_list(it->desc, &vals); - if (std::find(vals.begin(), vals.end(), now) == vals.end()) - ret = SCANNER_ERR_INVALID_PARAMETER; - else - { - ret = set_string(opt_ind_paper_, now, it->desc->size); - } - } - } - else - { - if (paper::is_lateral(now.c_str())) - { - size_t pos = now.find(paper::lateral_title()); - - if (pos != std::string::npos) - { - now.erase(pos); - ret = set_string(opt_ind_paper_, now, it->desc->size); - } - } - } - - return ret; -} -bool scanner::twain_is_paper_lateral(void) -{ - FIND_OPTION(opt_ind_paper_); - if (it == options_.end()) - return false; - - std::string now(get_string(opt_ind_paper_, it->desc->size)); - - return paper::is_lateral(now.c_str()); -} -int scanner::twain_set_paper_auto_match_size(bool match) -{ - FIND_OPTION(opt_ind_paper_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - std::string val(match ? paper::auto_size_title() : *it->val.sv); - - return set_string(opt_ind_paper_, val, it->desc->size); -} -bool scanner::twain_is_paper_auto_match_size(void) -{ - FIND_OPTION(opt_ind_paper_); - if (it == options_.end()) - return false; - - std::string now(get_string(opt_ind_paper_, it->desc->size)); - - return paper::is_auto_size(now.c_str()); -} - -int scanner::twain_set_scan_count(int count) -{ - int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - - if (opt_ind_scann_count_ != -1) - { - SANE_Int afterdo = 0; - char buf[80] = { 0 }; - - strcpy(buf, scan_count::scan_continous_val().c_str()); - if (count == -1) - { - ret = sane_invoker::invoke_sane_control_option(hdev_, HIWORD(opt_ind_scann_count_), SANE_ACTION_SET_VALUE, buf, &afterdo); - } - else - { - std::list vals; - std::string now(""), init(""); - - get_value(HIWORD(opt_ind_scann_count_), vals, now, init); - for (const auto& v : vals) - { - if (v != buf) - { - init = v; - break; - } - } - strcpy(buf, init.c_str()); - ret = sane_invoker::invoke_sane_control_option(hdev_, HIWORD(opt_ind_scann_count_), SANE_ACTION_SET_VALUE, buf, &afterdo); - if (ret == SANE_STATUS_GOOD) - { - SANE_Int v = count; - ret = sane_invoker::invoke_sane_control_option(hdev_, LOWORD(opt_ind_scann_count_), SANE_ACTION_SET_VALUE, &v, &afterdo); - } - } - } - - return ret; -} -int scanner::twain_get_scan_count(void) -{ - int ret = -1; - - if (opt_ind_scann_count_ != -1) - { - char buf[80] = { 0 }; - SANE_Int afterdo = 0, count = -1; - - ret = sane_invoker::invoke_sane_control_option(hdev_, HIWORD(opt_ind_scann_count_), SANE_ACTION_GET_VALUE, buf, &afterdo); - if (scan_count::scan_continous_val() == buf) - ret = -1; - else - { - sane_invoker::invoke_sane_control_option(hdev_, LOWORD(opt_ind_scann_count_), SANE_ACTION_GET_VALUE, &count, &afterdo); - ret = count; - } - } - - return ret; -} - -int scanner::twain_set_final_format(SANE_ImageType type, void* param) -{ - SANE_FinalImgFormat fmt; - unsigned int len = sizeof(fmt); - int ret = SCANNER_ERR_OK; - - fmt.img_format = type; - fmt.detail = param; - ret = sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_SET_FINAL_IMAGE_FORMAT, &fmt, &len); - if (ret == SCANNER_ERR_OK) - { - if (type == SANE_IMAGE_TYPE_JPG) - jpeg_quality_ = (int)param; - img_fmt_ = type; - } - - return ret; -} -int scanner::twain_get_jpeg_quality(void) -{ - return jpeg_quality_; -} -SANE_ImageType scanner::get_final_format(void) -{ - return img_fmt_; -} - -int scanner::twain_set_final_compression(int compression) -{ - SANE_Compression compr; - unsigned int len = sizeof(compr); - int ret = SCANNER_ERR_OK; - - compr.compression = (SANE_CompressionType)compression; - compr.detail = NULL; - - ret = sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_SET_FINAL_COMPRESSION, &compr, &len); - if (ret == SCANNER_ERR_OK || ret == SCANNER_ERR_NOT_EXACT) - compression_ = compr.compression; - - return ret; -} -int scanner::twain_get_final_compression(int* init, std::vector* values) -{ - if (init || values) - { - SANE_Int vals[80] = { 0 }; - unsigned int len = _countof(vals) - 4; - int ret = sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_FINAL_COMPRESSION, vals, &len); - - if (ret == SCANNER_ERR_OK) - { - if (init) - *init = vals[1]; - if (values) - { - for (int i = 0; i < vals[0]; ++i) - values->push_back(vals[3 + i]); - } - } - compression_ = (SANE_CompressionType)vals[2]; - } - - return compression_; -} - -int scanner::twain_set_text_direction(double degree) -{ - int ret = SCANNER_ERR_INVALID_PARAMETER; - std::string val(text_direction::from_twain_angle(degree)); - - if (val.length()) - { - FIND_OPTION(opt_ind_text_direction_); - if (it != options_.end()) - { - ret = set_string(opt_ind_text_direction_, val, it->desc->size); - } - } - - return ret; -} -double scanner::twain_get_text_direction(double* init, std::list* vals, value_limit* limit) -{ - double dir = .0f; - FIND_OPTION(opt_ind_text_direction_); - - if (it != options_.end()) - { - if (init) - *init = text_direction::to_twain_angle(it->val.sv->c_str()); - - if (vals) - { - std::list values; - sane_trans::get_value_list(it->desc, &values); - for (const auto& v : values) - vals->push_back(text_direction::to_twain_angle(v.c_str())); - - if (limit) - *limit = scanner::limit(it->desc->constraint_type); - } - - dir = text_direction::to_twain_angle(get_string(opt_ind_text_direction_, it->desc->size).c_str()); - } - - return dir; -} -int scanner::twain_set_text_auto_matic(bool am) -{ - FIND_OPTION(opt_ind_text_direction_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - std::string val(am ? text_direction::auto_val() : text_direction::from_twain_angle(0)); - - return set_string(opt_ind_text_direction_, val, it->desc->size); -} -bool scanner::twain_is_text_auto_matic(void) -{ - FIND_OPTION(opt_ind_text_direction_); - if (it == options_.end()) - return false; - - return text_direction::is_auto(get_string(opt_ind_text_direction_, it->desc->size).c_str()); -} - -int scanner::twain_set_page_duplex(bool dup) -{ - std::string val(page::from_duplex(dup)); - FIND_OPTION(opt_ind_page_); - - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - return set_string(opt_ind_page_, val, it->desc->size); -} -bool scanner::twain_is_page_duplex(void) -{ - FIND_OPTION(opt_ind_page_); - if (it == options_.end()) - return true; - - std::string now(get_string(opt_ind_page_, it->desc->size)); - - return page::is_duplex(now.c_str()); -} -int scanner::twain_set_page_discarding_blank_page(bool discard, bool receipt) -{ - std::string val(discard ? page::discard_blank_page_title(receipt) : page::from_duplex(true)); - FIND_OPTION(opt_ind_page_); - - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - return set_string(opt_ind_page_, val, it->desc->size); -} -bool scanner::twain_is_page_discarding_blank_page(bool receipt) -{ - FIND_OPTION(opt_ind_page_); - if (it == options_.end()) - return true; - - std::string now(get_string(opt_ind_page_, it->desc->size)); - - return page::is_discard_blank_page(now.c_str(), receipt); -} -int scanner::twain_set_page_fold(bool fold) -{ - std::string val(page::fold_page_title()); - FIND_OPTION(opt_ind_page_); - - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - return set_string(opt_ind_page_, val, it->desc->size); -} -bool scanner::twain_is_page_fold(void) -{ - FIND_OPTION(opt_ind_page_); - if (it == options_.end()) - return true; - - std::string now(get_string(opt_ind_page_, it->desc->size)); - - return page::is_fold(now.c_str()); -} - -int scanner::twain_set_auto_descrew(bool enable) -{ - FIND_OPTION(opt_ind_auto_descrew_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - SANE_Bool v = enable; - SANE_Int after = 0; - - return sane_invoker::invoke_sane_control_option(hdev_, opt_ind_auto_descrew_, SANE_ACTION_SET_VALUE, &v, &after); -} -bool scanner::twain_is_auto_descrew(void) -{ - return get_boolean(opt_ind_auto_descrew_); -} - -int scanner::twain_set_erase_black_frame(bool erase) -{ - FIND_OPTION(opt_ind_erase_black_frame_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - SANE_Bool v = erase; - SANE_Int after = 0; - - return sane_invoker::invoke_sane_control_option(hdev_, opt_ind_erase_black_frame_, SANE_ACTION_SET_VALUE, &v, &after); -} -bool scanner::twain_is_erase_black_frame(bool* init) -{ - FIND_OPTION(opt_ind_erase_black_frame_); - if (it == options_.end()) - return false; - - if (init) - *init = it->val.bv; - - return get_boolean(opt_ind_erase_black_frame_); -} - -int scanner::twain_set_filter(int tw_filter, bool enhance) -{ - FIND_OPTION(opt_ind_filter_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - std::string val(filter::from_filter_type(tw_filter, enhance)); - - return set_string(opt_ind_filter_, val, it->desc->size); -} -int scanner::twain_get_filter(bool enhance) -{ - FIND_OPTION(opt_ind_filter_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - std::string val(get_string(opt_ind_filter_, it->desc->size)); - - return filter::to_filter_type(val.c_str(), enhance); -} - -int scanner::twain_set_bright(double bright) -{ - FIND_OPTION(opt_ind_bright_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - SANE_Fixed v = SANE_FIX(bright); - SANE_Int after = 0; - - return sane_invoker::invoke_sane_control_option(hdev_, opt_ind_bright_, SANE_ACTION_SET_VALUE, &v, &after); -} -double scanner::twain_get_bright(double* init, double* lower, double* upper, double* step) -{ - FIND_OPTION(opt_ind_bright_); - if (it == options_.end()) - return .0f; - - if(lower && upper) - sane_trans::get_value_range(it->desc, lower, upper); - if (init) - *init = it->val.dv; - if (step) - *step = 1.0f; - - return get_double(opt_ind_bright_); -} - -int scanner::twain_set_contrast(double bright) -{ - FIND_OPTION(opt_ind_contrast_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - SANE_Fixed v = SANE_FIX(bright); - SANE_Int after = 0; - - return sane_invoker::invoke_sane_control_option(hdev_, opt_ind_contrast_, SANE_ACTION_SET_VALUE, &v, &after); -} -double scanner::twain_get_contrast(double* init, double* lower, double* upper, double* step) -{ - FIND_OPTION(opt_ind_contrast_); - if (it == options_.end()) - return .0f; - - if (lower && upper) - sane_trans::get_value_range(it->desc, lower, upper); - if (init) - *init = it->val.dv; - if (step) - *step = 1.0f; - - return get_double(opt_ind_contrast_); -} - -int scanner::twain_set_gamma(double bright) -{ - FIND_OPTION(opt_ind_gamma_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - SANE_Fixed v = SANE_FIX(bright); - SANE_Int after = 0; - - return sane_invoker::invoke_sane_control_option(hdev_, opt_ind_gamma_, SANE_ACTION_SET_VALUE, &v, &after); -} -double scanner::twain_get_gamma(double* init, double* lower, double* upper, double* step) -{ - FIND_OPTION(opt_ind_gamma_); - if (it == options_.end()) - return .0f; - - if (lower && upper) - sane_trans::get_value_range(it->desc, lower, upper); - if (init) - *init = it->val.dv; - if (step) - *step = 1.0f; - - return get_double(opt_ind_gamma_); -} - -int scanner::twain_set_ultrasonic_check(bool check) -{ - FIND_OPTION(opt_ind_ultrasonic_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - SANE_Bool v = check; - SANE_Int after = 0; - - return sane_invoker::invoke_sane_control_option(hdev_, opt_ind_ultrasonic_, SANE_ACTION_SET_VALUE, &v, &after); -} -bool scanner::twain_is_ultrasonic_check(bool* init) -{ - FIND_OPTION(opt_ind_ultrasonic_); - if (it == options_.end()) - return false; - - if (init) - *init = it->val.bv; - - return get_boolean(opt_ind_ultrasonic_); -} - -bool scanner::twain_is_auto_crop(void) -{ - return auto_crop_; -} -bool scanner::twain_is_paper_on(void) -{ - SANE_Bool on = false; - unsigned int len = sizeof(on); - - sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_PAPER_ON, &on, &len); - - return on; -} -int scanner::twain_get_device_code(char* buf, unsigned int len) -{ - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_DEVICE_CODE, buf, &len); -} - -int scanner::twain_set_sharpen(int sharpen) -{ - std::string val(sharpen::from_type(sharpen)); - FIND_OPTION(opt_ind_sharpen_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - return set_string(opt_ind_sharpen_, val, it->desc->size); -} -int scanner::twain_get_sharpen(void) -{ - FIND_OPTION(opt_ind_sharpen_); - if (it == options_.end()) - return SHARPEN_NONE; - - std::string now(get_string(opt_ind_sharpen_, it->desc->size)); - - return sharpen::to_type(now.c_str()); -} - -int scanner::twain_get_serial_num(char buf[]) -{ - unsigned int len = 240; - - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_SERIAL, buf, &len); -} -int scanner::twain_get_hareware_version(char buf[]) -{ - unsigned int len = 240; - - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_HARDWARE_VERSION, buf, &len); -} -int scanner::twain_get_ip(char buf[]) -{ - unsigned int len = 240; - - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_IP, buf, &len); -} - -int scanner::twain_get_dogear_distance(void) -{ - SANE_Int v = 0; - unsigned int len = sizeof(v); - - sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_DOGEAR_DISTANCE, &v, &len); - - return v; -} -int scanner::twain_set_dogear_distance(int dist) -{ - SANE_Int v = dist; - unsigned int len = sizeof(v); - - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_SET_DOGEAR_DISTANCE, &v, &len); -} - -int scanner::twain_set_power_level(int level) -{ - SANE_Power v = (SANE_Power)level; - unsigned int len = sizeof(v); - - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_SET_POWER_LEVEL, &v, &len); -} -int scanner::twain_get_power_level(void) -{ - SANE_Power v = SANE_POWER_NONE; - unsigned int len = sizeof(v); - - sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_POWER_LEVEL, &v, &len); - - return v; -} - -int scanner::twain_set_to_be_scan(bool yes) -{ - SANE_Bool v = yes; - unsigned int len = sizeof(v); - - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_SET_SCAN_WHEN_PAPER_ON, &v, &len); -} -bool scanner::twain_get_to_be_scan(void) -{ - SANE_Bool v = 0; - unsigned int len = sizeof(v); - - sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_SCAN_WHEN_PAPER_ON, &v, &len); - - return v; -} - -int scanner::twain_set_scan_with_hole(bool yes) -{ - SANE_Bool v = yes; - unsigned int len = sizeof(v); - - return sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_SET_SCAN_WITH_HOLE, &v, &len); -} -bool scanner::twain_get_scan_with_hole(void) -{ - SANE_Bool v = 0; - unsigned int len = sizeof(v); - - sane_invoker::invoke_sane_io_control(hdev_, IO_CTRL_CODE_GET_SCAN_WITH_HOLE, &v, &len); - - return v; -} - -int scanner::twain_set_multioutput_type(int type) -{ - FIND_OPTION(opt_ind_multi_out_); - if (it == options_.end()) - return SCANNER_ERR_NOT_OPEN; - - std::string val(multi_out::from_twain_type(type)); - - return set_string(opt_ind_multi_out_, val, it->desc->size); -} -int scanner::twain_get_multioutput_type(void) -{ - FIND_OPTION(opt_ind_multi_out_); - if (it == options_.end()) - return MULTI_OUT_NONE; - - std::string now(get_string(opt_ind_multi_out_, it->desc->size)); - - return multi_out::to_twain_type(now.c_str()); -} - -int scanner::twain_get_flip_ind(void) -{ - return opt_ind_flip_; -} -int scanner::twain_get_rotate_bkg_ind(void) -{ - return opt_ind_rotate_bkg_; -} -int scanner::twain_get_fill_black_bkg_ind(void) -{ - return opt_ind_fill_blank_bkg_; -} -int scanner::twain_get_edge_ident_ind(void) -{ - return opt_ind_edge_ident_; -} -int scanner::twain_get_threshold_ind(void) -{ - return opt_ind_threshold_; -} -int scanner::twain_bkg_filling_method_ind(void) -{ - return opt_ind_bkg_filling_method_; -} -int scanner::twain_fill_hole_ind(void) -{ - return opt_ind_fill_hole_; -} -int scanner::twain_fill_hole_ratio_ind(void) -{ - return opt_ind_fill_hole_ratio_; -} -int scanner::twain_detach_noise_ind(void) -{ - return opt_ind_noise_; -} -int scanner::twain_detach_noise_threshold_ind(void) -{ - return opt_ind_noise_threshold_; -} -int scanner::twain_rid_red_ind(void) -{ - return opt_ind_rid_red_; -} -int scanner::twain_rid_red_hsv_ind(void) -{ - return opt_ind_rid_red_hsv_; -} -int scanner::twain_screw_detect_ind(void) -{ - return opt_ind_screw_detect_; -} -int scanner::twain_screw_detect_level_ind(void) -{ - return opt_ind_screw_detect_level_; -} -int scanner::twain_staple_detect_ind(void) -{ - return opt_ind_staple_; -} -int scanner::twain_dogear_detect_ind(void) -{ - return opt_ind_dogear_; -} -int scanner::twain_dark_sample_ind(void) -{ - return opt_ind_dark_sample_; -} -int scanner::twain_image_split_ind(void) -{ - return opt_ind_split_; -} -int scanner::twain_fade_bkground_ind(void) -{ - return opt_ind_fade_bkg_; -} -int scanner::twain_fade_bkground_val_ind(void) -{ - return opt_ind_fade_bkg_val_; -} -int scanner::twain_size_detect_ind(void) -{ - return opt_ind_size_detect_; -} - - diff --git a/sane/huagaotwain.h b/sane/huagaotwain.h deleted file mode 100644 index cfb5d21..0000000 --- a/sane/huagaotwain.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "huagao/hgscanner_error.h" -#include -#include -#include -#include -#include "sane_option_trans.h" -#include "s2t_api.h" - - - - diff --git a/sane/mem_dc.cpp b/sane/mem_dc.cpp deleted file mode 100644 index 742e161..0000000 --- a/sane/mem_dc.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// DlgIndicator.cpp: 实现文件 -// - -#include "mem_dc.h" - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// - - - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// compatible_dc -compatible_dc::compatible_dc(HDC src) : src_(src), old_(NULL) -{ - HWND hwnd = WindowFromDC(src); - RECT r = { 0 }; - - if (!IsWindow(hwnd)) - hwnd = GetDesktopWindow(); - GetWindowRect(hwnd, &r); - size_.cx = r.right - r.left; - size_.cy = r.bottom - r.top; - bmp_ = CreateCompatibleBitmap(src, size_.cx, size_.cy); - hdc_ = CreateCompatibleDC(src); - old_ = (HBITMAP)SelectObject(hdc_, bmp_); - BitBlt(hdc_, 0, 0, size_.cx, size_.cy, src, 0, 0, SRCCOPY); -} -compatible_dc::~compatible_dc() -{ - BitBlt(src_, 0, 0, size_.cx, size_.cy, hdc_, 0, 0, SRCCOPY); - SelectObject(hdc_, old_); - DeleteObject(bmp_); - DeleteDC(hdc_); -} - -HDC compatible_dc::get_dc() -{ - return hdc_; -} \ No newline at end of file diff --git a/sane/mem_dc.h b/sane/mem_dc.h deleted file mode 100644 index 0c18603..0000000 --- a/sane/mem_dc.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -class compatible_dc -{ - HBITMAP bmp_; - HBITMAP old_; - HDC hdc_; - HDC src_; - SIZE size_; - -public: - compatible_dc(HDC src); - ~compatible_dc(); - -public: - HDC get_dc(void); -}; \ No newline at end of file diff --git a/sane/s2t_api.h b/sane/s2t_api.h deleted file mode 100644 index d1eff00..0000000 --- a/sane/s2t_api.h +++ /dev/null @@ -1,457 +0,0 @@ -#pragma once - -// -// For: interface definition for SANE to TWAIN -// -// Date: 2022-06-08 -// - -#include -#include -#include -#include - -#define COM_API_DECLARE(ret, decl) virtual ret __stdcall decl = 0 -#define COM_API_DECLARE_NON_PURE(ret, decl) virtual ret __stdcall decl -#define COM_API_OVERRIDE(ret, decl) virtual ret __stdcall decl override -#define COM_API_IMPLEMENT(cls, ret, decl) ret __stdcall cls##::decl - -#define SANE_OPTION_ID_API(opt) COM_API_DECLARE(int, sane_opt_id_##opt(void)) // -1 is none -#define SANE_OPTION_ID_OVERRIDE(opt) COM_API_OVERRIDE(int, sane_opt_id_##opt(void)) -#define SANE_OPTION_IMPLEMENT(cls, opt) int __stdcall cls##::sane_opt_id_##opt(void) - -#define SANE_OPTION_ID_API_EX(opt) COM_API_DECLARE(int, sane_opt_id_ex_##opt(void)) // -1 is none -#define SANE_OPTION_ID_OVERRIDE_EX(opt) COM_API_OVERRIDE(int, sane_opt_id_ex_##opt(void)) -#define SANE_OPTION_IMPLEMENT_EX(cls, opt) int __stdcall cls##::sane_opt_id_ex_##opt(void) - - -#define ALIGN_MEMORY(n, align) ((n + align - 1) / (align) * (align)) -#define _TO_UNICODE_(str) L##str -#define UNICODE_STR(str) _TO_UNICODE_(str) - -#define TWPT_AUTOMATIC_COLOR 0x0a0c -#define AUTO_MATIC_ROTATE 123.456f -#define IS_DOUBLE_EQUAL(a, b) fabs((a) - (b)) < .000001 - -enum value_limit -{ - VAL_LIMIT_NONE = 0, // - VAL_LIMIT_ENUM, // - VAL_LIMIT_RANGE, // -}; -enum value_role -{ - VAL_ROLE_NONE = 0, // this value is no role but an item of the option only - VAL_ROLE_DEFAULT = 0x01, // this value is the default value of the option - VAL_ROLE_CURRENT = 0x02, // this value is the current value of the option - VAL_ROLE_LOWER = 0x04, // the lower value of a VAL_LIMIT_RANGE - VAL_ROLE_UPPER = 0x08, // the upper value of a VAL_LIMIT_RANGE - VAL_ROLE_STEP = 0x10, // the step value of a VAL_LIMIT_RANGE -}; -enum value_type -{ - VAL_TYPE_NONE = 0, - VAL_TYPE_BOOL, // bool - VAL_TYPE_INT, // int - VAL_TYPE_FLOAT, // float - VAL_TYPE_STR, // char* - VAL_TYPE_BUTTON, // a button -}; -enum color_value // 除最后一项外,其余与Twpp::PixelType值保持一致 -{ - COLOR_BW = 0, - COLOR_GRAY, - COLOR_RGB, - COLOR_AUTO_MATCH = TWPT_AUTOMATIC_COLOR, -}; -enum paper_value // 与Twpp::PaperSize保持一致 -{ - PAPER_A4 = 1, - PAPER_16K = 1, - PAPER_LETTER = 3, - PAPER_LEGAL = 4, - PAPER_A5 = 5, - PAPER_B4 = 6, - PAPER_B6 = 7, - PAPER_A3 = 11, - PAPER_8K = 11, - PAPER_A6 = 13, - PAPER_B5 = 29, - PAPER_STATEMENT = 52, // 匹配原始尺寸 - PAPER_MAXSIZE = 54, // 最大扫描尺寸 - - // 以下为未匹配选项 - PAPER_DOUBLE_LETTER = 103, - PAPER_MAXSIZE_CROP = 154, // 最大扫描尺寸自动裁切 - PAPER_TRIPPLE = 111, // 三联试卷 -}; -enum filter_value // 除色选项 -{ - FILTER_NONE = 0, - FILTER_RED, - FILTER_GREEN, - FILTER_BLUE, -}; -enum enhance_value // 颜色增强选项 -{ - ENHANCE_NONE = 0, - ENHANCE_RED, - ENHANCE_GREEN, - ENHANCE_BLUE, -}; -enum sharpen_value -{ - SHARPEN_NONE = 0, - SHARPEN_SHARPEN, - SHARPEN_SHARPEN_MORE, - SHARPEN_BLUR, - SHARPEN_BLUR_MORE, -}; -enum multiout_value -{ - MULTI_OUT_NONE = -1, - MULTI_OUT_ALL, - MULTI_OUT_COLOR_GRAY, - MULTI_OUT_COLOR_BW, - MULTI_OUT_GRAY_BW, -}; -enum twain_xfer -{ - TWAIN_XFER_Native = 0, // BITMAPINFOHEADER + bits - TWAIN_XFER_File = 1, // BITMAPFILEHEADER + TWAIN_XFER_Native - TWAIN_XFER_Memory = 2, // to be implementing ... -}; - -typedef bool(__stdcall* set_opt_value)(void* val, value_role role, value_limit limit, void* param); // return false to stop the callback -struct __declspec(novtable) IRef -{ - COM_API_DECLARE(long, add_ref(void)); - COM_API_DECLARE(long, release(void)); -}; -struct __declspec(novtable) IScanImg : public IRef -{ - COM_API_DECLARE(int, width(void)); - COM_API_DECLARE(int, line_bytes(void)); - COM_API_DECLARE(int, height(void)); - COM_API_DECLARE(int, depth(void)); - COM_API_DECLARE(int, channel(void)); - COM_API_DECLARE(int, dpi(void)); - COM_API_DECLARE(SANE_Frame, type(void)); - COM_API_DECLARE(unsigned int, bytes(void)); - COM_API_DECLARE(unsigned int, header_size(void)); - COM_API_DECLARE(unsigned char*, data(unsigned long long off, unsigned int *bytes)); - COM_API_DECLARE(int, read(void* buf, size_t* bytes, unsigned long long off = 0)); - COM_API_DECLARE(const char*, file(void)); - COM_API_DECLARE(void, keep_file(bool keep)); - COM_API_DECLARE(void, copy_header(SANE_Parameters* head)); - COM_API_DECLARE(int, image_status(void)); -}; -struct __declspec(novtable) ISaneInvoker : public IRef -{ - COM_API_DECLARE(int, start(void)); - COM_API_DECLARE(int, stop(void)); - COM_API_DECLARE(int, get_event(void)); - COM_API_DECLARE(void, set_event_callback(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL)); - COM_API_DECLARE(bool, wait_image(DWORD milliseconds = -1)); - COM_API_DECLARE(int, get_scanned_images(DWORD milliseconds = 0)); - COM_API_DECLARE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz - COM_API_DECLARE(bool, get_first_image_header(SANE_Parameters* header, size_t* bytes = NULL, int *dpi = NULL)); - COM_API_DECLARE(bool, is_online(void)); - COM_API_DECLARE(bool, is_paper_on(void)); - COM_API_DECLARE(int, last_error(void)); - - // Function: 获取配置项信息 - // - // Parameter: sn - 配置项索引 - // - // type - 配置项数据类型 - // - // limit - 配置项限制类型 - // - // bytes - *type 为 VAL_TYPE_STR时,需要的最小空间字节数 - COM_API_DECLARE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int *bytes)); - - COM_API_DECLARE(bool, get_value(int sn, set_opt_value, void* param)); - COM_API_DECLARE(int, set_value(int sn, void* val)); - COM_API_DECLARE(int, convert_image(SANE_ImageFormatConvert* conv)); - COM_API_DECLARE(void, free_buffer(void* buf, int len)); - - // SANE options ID ... - SANE_OPTION_ID_API(color_correction); // 2023-02-24 15:31:19 色偏校正 - SANE_OPTION_ID_API(fold_type); // 2023-02-24 15:28:47 对折模式 - SANE_OPTION_ID_API(is_multiout); // 多流输出 - SANE_OPTION_ID_API(multiout_type); // 多流输出类型 - SANE_OPTION_ID_API(color_mode); // 颜色模式 - SANE_OPTION_ID_API(erase_color); // 除色或增强 - SANE_OPTION_ID_API(erase_multiout_red); // 多流输出除红 - SANE_OPTION_ID_API(erase_paper_red); // 试卷除红 - SANE_OPTION_ID_API(is_erase_background); // 背景移除 - SANE_OPTION_ID_API(background_color_range); // 背景色彩范围 - SANE_OPTION_ID_API(sharpen); // 锐化与模糊 - SANE_OPTION_ID_API(erase_morr); // 除摩尔纹 - SANE_OPTION_ID_API(erase_grids); // 除网纹 - SANE_OPTION_ID_API(error_extend); // 错误扩散 - SANE_OPTION_ID_API(is_noise_modify); // 噪点优化 - SANE_OPTION_ID_API(noise_threshold); // 噪点优化尺寸 - SANE_OPTION_ID_API(paper); // 纸张尺寸 - SANE_OPTION_ID_API(is_custom_area); // 自定义扫描区域 - SANE_OPTION_ID_API(curstom_area_l); // 自定义扫描区域 左 - SANE_OPTION_ID_API(curstom_area_r); // 自定义扫描区域 右 - SANE_OPTION_ID_API(curstom_area_t); // 自定义扫描区域 上 - SANE_OPTION_ID_API(curstom_area_b); // 自定义扫描区域 下 - SANE_OPTION_ID_API(is_size_check); // 尺寸检测 - SANE_OPTION_ID_API(page); // 扫描页面 - SANE_OPTION_ID_API(blank_page_threshold); // 跳过空白页灵敏度 - SANE_OPTION_ID_API(resolution); // 分辨率 - SANE_OPTION_ID_API(image_quality); // 图像质量 - SANE_OPTION_ID_API(is_swap); // 交换正反面 - SANE_OPTION_ID_API(is_split); // 图像拆分 - SANE_OPTION_ID_API(is_auto_deskew); // 自动纠偏 - SANE_OPTION_ID_API(is_custom_gamma); // 自定义gamma - SANE_OPTION_ID_API(bright); // 亮度 - SANE_OPTION_ID_API(contrast); // 对比度 - SANE_OPTION_ID_API(gamma); // gamma - SANE_OPTION_ID_API(is_erase_black_frame); // 消除黑框 - SANE_OPTION_ID_API(deep_sample); // 深色样张 - SANE_OPTION_ID_API(threshold); // 阈值 - SANE_OPTION_ID_API(anti_noise); // 背景抗噪等级 - SANE_OPTION_ID_API(margin); // 边缘缩进 - SANE_OPTION_ID_API(fill_background); // 背景填充方式 - SANE_OPTION_ID_API(is_anti_permeate); // 防止渗透 - SANE_OPTION_ID_API(anti_permeate_level); // 防止渗透等级 - SANE_OPTION_ID_API(is_erase_hole); // 穿孔移除 - SANE_OPTION_ID_API(search_hole_range); // 穿孔搜索范围 - SANE_OPTION_ID_API(is_filling_color); // 色彩填充 - SANE_OPTION_ID_API(is_ultrasonic_check); // 超声波检测 - SANE_OPTION_ID_API(is_check_staple); // 装订检测 - SANE_OPTION_ID_API(scan_mode); // 扫描张数 - SANE_OPTION_ID_API(scan_count); // 扫描数量 - SANE_OPTION_ID_API(text_direction); // 文稿方向 - SANE_OPTION_ID_API(is_rotate_bkg180); // 背面旋转180度 - SANE_OPTION_ID_API(is_check_dogear); // 折角检测 - SANE_OPTION_ID_API(dogear_size); // 折角检测大小 - SANE_OPTION_ID_API(is_check_skew); // 歪斜检测 - SANE_OPTION_ID_API(skew_range); // 歪斜容忍度 - SANE_OPTION_ID_API(black_white_threshold); // 二值化图像阈值 - SANE_OPTION_ID_API(is_photo_mode); // 照片模式 - SANE_OPTION_ID_API(double_feed_handle); // 双张图片处理 - SANE_OPTION_ID_API(scan_when_paper_on); // 待纸扫描 - SANE_OPTION_ID_API(feed_strength); // 分纸强度 - SANE_OPTION_ID_API(power_scheme); // 休眠时间 - SANE_OPTION_ID_API(is_auto_strength); // 自动搓纸强度 - SANE_OPTION_ID_API(feed_strength_value); // 自动搓纸强度设定值 - SANE_OPTION_ID_API(is_reverse_bw); // 黑白图像反色输出 - SANE_OPTION_ID_API(is_erase_hole_l); // 穿孔移除 - 左 - SANE_OPTION_ID_API(search_hole_range_l); // 穿孔搜索范围 - 左 - SANE_OPTION_ID_API(is_erase_hole_r); // 穿孔移除 - 右 - SANE_OPTION_ID_API(search_hole_range_r); // 穿孔搜索范围 - 右 - SANE_OPTION_ID_API(is_erase_hole_t); // 穿孔移除 - 上 - SANE_OPTION_ID_API(search_hole_range_t); // 穿孔搜索范围 - 上 - SANE_OPTION_ID_API(is_erase_hole_b); // 穿孔移除 - 下 - SANE_OPTION_ID_API(search_hole_range_b); // 穿孔搜索范围 - 下 - SANE_OPTION_ID_API(fold_direction); // 对折模式 - - // SANE-ex option ID: - SANE_OPTION_ID_API_EX(multiout_type); // int - SANE_OPTION_ID_API_EX(auto_color_type); // int - SANE_OPTION_ID_API_EX(color_mode); // int - SANE_OPTION_ID_API_EX(sharpen); // int - SANE_OPTION_ID_API_EX(paper); // paper_value - SANE_OPTION_ID_API_EX(paper_lateral); // bool - SANE_OPTION_ID_API_EX(auto_paper_size); // bool - SANE_OPTION_ID_API_EX(is_paper_auto_crop); // bool - SANE_OPTION_ID_API_EX(text_direction); // float 90, 180, ..., -1 is auto-text-direction - SANE_OPTION_ID_API_EX(duplex); // bool - SANE_OPTION_ID_API_EX(fill_background); // bool true - 凸多边形 - SANE_OPTION_ID_API_EX(discard_blank_page); // bool - SANE_OPTION_ID_API_EX(discard_blank_receipt); // bool - SANE_OPTION_ID_API_EX(is_page_fold); // bool - SANE_OPTION_ID_API_EX(color_filter); // int (filter_value) - SANE_OPTION_ID_API_EX(color_enhance); // int (enhance_value) - - SANE_OPTION_ID_API_EX(final_compression); // int - SANE_OPTION_ID_API_EX(final_format); // SANE_FinalImgFormat - SANE_OPTION_ID_API_EX(serial); // std::string - SANE_OPTION_ID_API_EX(to_be_scan); // bool - SANE_OPTION_ID_API_EX(scan_with_hole); // bool - SANE_OPTION_ID_API_EX(device_code); // std::string - SANE_OPTION_ID_API_EX(power); // int - SANE_OPTION_ID_API_EX(hardware_version); // std::string - SANE_OPTION_ID_API_EX(ip); // std::string - - // ui ... - COM_API_DECLARE(bool, ui_show_main(HWND parent)); - COM_API_DECLARE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true)); - COM_API_DECLARE(bool, ui_show_progress(HWND parent)); - COM_API_DECLARE(void, ui_hide(void)); - COM_API_DECLARE(bool, ui_is_ok(void)); - - // twain - COM_API_DECLARE(void, twain_set_transfer(twain_xfer xfer)); - COM_API_DECLARE(void, twain_set_compression(SANE_CompressionType compression, void* detail = NULL)); - COM_API_DECLARE(int, twain_get_config(char* buf, size_t* len)); - COM_API_DECLARE(int, twain_set_config(char* buf, size_t len)); -}; - -struct delete_scanner -{ - void operator()(ISaneInvoker* p) - { - p->release(); - } -}; - -#include -#include -namespace sane_opts -{ - enum - { - RANGE_POS_CURRENT = 0, - RANGE_POS_DEFAULT, - RANGE_POS_ENUM_BEGIN, - RANGE_POS_LOWER = RANGE_POS_ENUM_BEGIN, - RANGE_POS_UPPER, - RANGE_POS_STEP, - }; - - template - class get_opts - { - public: - // 0 - cur val; 1 - def val; - // - // LIST: 2 - elements ... - // - // RANGE: 2 - lower; 3 - upper; 4 - step - T range[5]; - value_limit lmt_; - - std::vector* lvs_; - value_limit* limit_; - - public: - get_opts(value_limit* limit, std::vector* ls) : limit_(limit), lvs_(ls) - {} - ~get_opts() - {} - - void re_order(void) - { - if (limit_) - *limit_ = lmt_; - - if (lmt_ == VAL_LIMIT_RANGE || lmt_ == VAL_LIMIT_NONE) - { - if (lvs_) - { - lvs_->clear(); - for (size_t i = 0; i < _countof(range); ++i) - lvs_->push_back(range[i]); - } - } - else if(lvs_) - { - lvs_->insert(lvs_->begin(), range[RANGE_POS_DEFAULT]); - lvs_->insert(lvs_->begin(), range[RANGE_POS_CURRENT]); - } - } - }; - - template - bool __stdcall set_opt_value(void* val, value_role role, value_limit limit, void* param) - { - get_opts* v = (get_opts*)param; - bool go = true; - - v->lmt_ = limit; - if (role & VAL_ROLE_CURRENT) - { - v->range[RANGE_POS_CURRENT] = *(T*)val; - } - if (role & VAL_ROLE_DEFAULT) - { - v->range[RANGE_POS_DEFAULT] = *(T*)val; - } - if (role & VAL_ROLE_LOWER) - { - v->range[RANGE_POS_LOWER] = *(T*)val; - } - if (role & VAL_ROLE_UPPER) - { - v->range[RANGE_POS_UPPER] = *(T*)val; - } - - if (role & VAL_ROLE_STEP) - { - v->range[RANGE_POS_STEP] = *(T*)val; - } - else if (v->lvs_) - v->lvs_->push_back(*(T*)val); - - return go; - } -} - -#define GET_SANE_OPT(type, object, id_name, limit, vct) \ - { \ - int ind = object->sane_opt_id_##id_name##(); \ - sane_opts::get_opts op(limit, vct); \ - if(ind > 0) \ - object->get_value(ind, sane_opts::set_opt_value, &op);\ - else \ - return capUnsupported(); \ - op.re_order(); \ - } - -#define SET_SANE_OPT(ret, object, id_name, val) \ - { \ - int ind = object->sane_opt_id_##id_name##(); \ - if(ind > 0) \ - ret = object->set_value(ind, val); \ - else \ - { \ - ret = SCANNER_ERR_INVALID_PARAMETER; \ - load_sane_util::log_info((std::wstring(L"Fatal: property '") + L###id_name + L"' not found !!!\r\n").c_str(), 0); \ - } \ - } - -typedef unsigned int SCANNERID; -#define MAKE_SCANNER_ID(pid, vid) MAKELONG(pid, vid) -#define GET_SCANNER_PID(sid) LOWORD(sid) -#define GET_SCANNER_VID(sid) HIWORD(sid) - -extern "C" -{ -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - int __stdcall initialize(void* reserve); -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - int __stdcall open_scanner(SCANNERID scanner_id, ISaneInvoker** invoker); -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - bool __stdcall is_scanner_online(SCANNERID scanner_id); -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - int __stdcall uninitialize(void* reserve); -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - void __stdcall log_info(const wchar_t* info, int level); -} - diff --git a/sane/sane.def b/sane/sane.def index 13abb0a..4232264 100644 --- a/sane/sane.def +++ b/sane/sane.def @@ -1,10 +1,5 @@ LIBRARY sane EXPORTS - initialize - open_scanner - is_scanner_online - uninitialize - log_info sane_hgsane_init sane_hgsane_exit sane_hgsane_get_devices diff --git a/sane/sane.vcxproj b/sane/sane.vcxproj index 8834c97..bb744c0 100644 --- a/sane/sane.vcxproj +++ b/sane/sane.vcxproj @@ -77,6 +77,7 @@ $(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ + true false @@ -84,6 +85,7 @@ $(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ + false true @@ -91,6 +93,7 @@ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\sdk\include;$(SolutionDir)..\..\code_device\include\;$(IncludePath) $(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) + true false @@ -98,6 +101,7 @@ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ $(SolutionDir)..\..\sdk\include;$(SolutionDir)..\..\code_device\include\;$(IncludePath) $(SolutionDir)..\..\sdk\lib\win\$(PlatformTarget)\$(Configuration);$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) + false @@ -118,8 +122,10 @@ - - + move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +copy /y "$(TargetPath)" "C:\Windows\twain_32\HuaGoTwain" @@ -144,8 +150,9 @@ UseLinkTimeCodeGeneration - - + move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" @@ -164,8 +171,10 @@ $(ProjectDir)sane.def - - + move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +copy /y "$(TargetPath)" "C:\Program Files\HuaGoScan" @@ -189,8 +198,9 @@ UseLinkTimeCodeGeneration - - + move /Y "$(TargetDir)$(ProjectName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(ProjectName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" @@ -199,19 +209,6 @@ - - - - - - - - - - - - - @@ -226,22 +223,7 @@ - - - - - - - - - - - - - - - diff --git a/sane/sane.vcxproj.filters b/sane/sane.vcxproj.filters index 73d0df0..febe37d 100644 --- a/sane/sane.vcxproj.filters +++ b/sane/sane.vcxproj.filters @@ -13,12 +13,6 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - {8ae15a45-410d-4611-b852-f82b64bb1fcc} - - - {5c86255e-570e-4921-9c62-c98d05edcab4} - @@ -36,45 +30,6 @@ 源文件 - - sane2twain - - - sane2twain - - - sane2twain - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - @@ -113,54 +68,9 @@ 头文件 - - sane2twain - - - sane2twain - - - sane2twain - - - sane2twain - 头文件 - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - - - sane2twain\UI - diff --git a/sane/sane_option_trans.cpp b/sane/sane_option_trans.cpp deleted file mode 100644 index 6e723c2..0000000 --- a/sane/sane_option_trans.cpp +++ /dev/null @@ -1,300 +0,0 @@ -#include "sane_option_trans.h" -#include -#include - -#include "../../sdk/include/lang/app_language.h" - -namespace sane_opt_trans -{ - static struct - { - int twain_id; - const char* opt_val; - } - g_color_mode_map[] = {{COLOR_BW, OPTION_VALUE_YSMS_HB} - , {COLOR_GRAY, OPTION_VALUE_YSMS_256JHD} - , {COLOR_RGB, OPTION_VALUE_YSMS_24WCS} - , {COLOR_AUTO_MATCH, OPTION_VALUE_YSMS_YSZDSB} - }, - g_multiout_map[] = { {MULTI_OUT_NONE, "\346\227\240"} - , {MULTI_OUT_ALL, OPTION_VALUE_DLSCLX_CS_HD_HB} - , {MULTI_OUT_COLOR_GRAY, OPTION_VALUE_DLSCLX_CS_HD} - , {MULTI_OUT_COLOR_BW, OPTION_VALUE_DLSCLX_CS_HB} - , {MULTI_OUT_GRAY_BW, OPTION_VALUE_DLSCLX_HD_HB} - }, - g_enhance_map[] = { {ENHANCE_NONE, OPTION_VALUE_HDHHBTX_CSYZQ_BCS} - , {ENHANCE_RED, OPTION_VALUE_HDHHBTX_CSYZQ_HSZQ} - , {ENHANCE_GREEN, OPTION_VALUE_HDHHBTX_CSYZQ_LSZQ} - , {ENHANCE_BLUE, OPTION_VALUE_HDHHBTX_CSYZQ_LANSEZENGQIANG} - }, - g_filter_map[] = { {FILTER_NONE, OPTION_VALUE_HDHHBTX_CSYZQ_BCS} - , {FILTER_RED, OPTION_VALUE_HDHHBTX_CSYZQ_CHS} - , {FILTER_GREEN, OPTION_VALUE_HDHHBTX_CSYZQ_CLS} - , {FILTER_BLUE, OPTION_VALUE_HDHHBTX_CSYZQ_CHULANSE} - }, - g_auto_color_map[] = { {0, OPTION_VALUE_YSMS_HB} - , {1, OPTION_VALUE_YSMS_256JHD} - }, - g_sharpen_map[] = { {SHARPEN_NONE, OPTION_VALUE_RHYMH_W} - , {SHARPEN_SHARPEN, OPTION_VALUE_RHYMH_RH} - , {SHARPEN_SHARPEN_MORE, OPTION_VALUE_RHYMH_JYBRH} - , {SHARPEN_BLUR, OPTION_VALUE_RHYMH_MH} - , {SHARPEN_BLUR_MORE, OPTION_VALUE_RHYMH_JYBMH} - }, - g_paper_map[] = { {PAPER_LETTER, OPTION_VALUE_ZZCC_Letter} - , {PAPER_LEGAL, OPTION_VALUE_ZZCC_LEGAL} - //, {PAPER_8K, OPTION_VALUE_ZZCC_8K} - //, {PAPER_16K, OPTION_VALUE_ZZCC_16K} - , {PAPER_A3, OPTION_VALUE_ZZCC_A3} - , {PAPER_A4, OPTION_VALUE_ZZCC_A4} - , {PAPER_A5, OPTION_VALUE_ZZCC_A5} - , {PAPER_A6, OPTION_VALUE_ZZCC_A6} - , {PAPER_B4, OPTION_VALUE_ZZCC_B4} - , {PAPER_B5, OPTION_VALUE_ZZCC_B5} - , {PAPER_B6, OPTION_VALUE_ZZCC_B6} - , {PAPER_STATEMENT, OPTION_VALUE_ZZCC_PPYSCC} - , {PAPER_MAXSIZE, OPTION_VALUE_ZZCC_ZDSMCC} - , {PAPER_MAXSIZE_CROP, OPTION_VALUE_ZZCC_ZDSMCCZDCQ} - , {PAPER_DOUBLE_LETTER, OPTION_VALUE_ZZCC_DoubleLetter} - , {PAPER_TRIPPLE, OPTION_VALUE_ZZCC_SLSJ} - } - ; -#define VALUE_FROM_TWAIN(arr, val) \ - for (int i = 0; i < _countof(arr); ++i) \ - { \ - if (arr[i].twain_id == val) \ - return from_default_language(arr[i].opt_val, NULL); \ - } -#define VALUE_TO_TWAIN(arr, val) \ - for (int i = 0; i < _countof(arr); ++i) \ - { \ - if (strcmp(from_default_language(arr[i].opt_val, NULL), val) == 0) \ - return arr[i].twain_id; \ - } - - const char* color_mode_from_twain(int val) - { - VALUE_FROM_TWAIN(g_color_mode_map, val); - - return OPTION_VALUE_YSMS_YSZDSB; - } - int color_mode_to_twain(const char* val) - { - VALUE_TO_TWAIN(g_color_mode_map, val); - - return COLOR_AUTO_MATCH; - } - - const char* multiout_value_from_twain(int val) - { - VALUE_FROM_TWAIN(g_multiout_map, val); - - return NULL; - } - int multiout_value_to_twain(const char* val) - { - VALUE_TO_TWAIN(g_multiout_map, val); - - return -1; - } - - const char* filter_enhance_value_from_twain(int val, bool filter) - { - if (filter) - { - for (int i = 0; i < _countof(g_filter_map); ++i) - { - if (g_filter_map[i].twain_id == val) - return from_default_language(g_filter_map[i].opt_val, NULL); - } - } - else - { - for (int i = 0; i < _countof(g_enhance_map); ++i) - { - if (g_enhance_map[i].twain_id == val) - return from_default_language(g_enhance_map[i].opt_val, NULL); - } - } - - return from_default_language(OPTION_VALUE_HDHHBTX_CSYZQ_BCS, NULL); - } - int filter_enhance_value_to_twain(const char* val, bool* is_filter) - { - bool type = false; - const char* hz = to_default_language(val, NULL); - - if (!is_filter) - is_filter = &type; - - *is_filter = true; - for (int i = 0; i < _countof(g_filter_map); ++i) - { - if (strcmp(g_filter_map[i].opt_val, hz) == 0) - return g_filter_map[i].twain_id; - } - *is_filter = false; - for (int i = 0; i < _countof(g_enhance_map); ++i) - { - if (strcmp(g_enhance_map[i].opt_val, hz) == 0) - return g_enhance_map[i].twain_id; - } - - return ENHANCE_NONE; - } - - const char* text_direction_from_twain(float val) - { - while (val < .0f) - val += 360.0f; - while (val > 360.0f) - val -= 360.0f; - - if (60.0f < val && val < 120.0f) - return from_default_language(OPTION_VALUE_WGFX_90, NULL); - else if (150.0f < val && val < 210.0f) - return from_default_language(OPTION_VALUE_WGFX_180, NULL); - else if (240.0f < val && val < 300.0f) - return from_default_language(OPTION_VALUE_WGFX__90, NULL); - else if (330.0f < val || val < 30.0f) - return from_default_language(OPTION_VALUE_WGFX_0, NULL); - else - return from_default_language(OPTION_VALUE_WGFX_ZDWBFXSB, NULL); - } - float text_direction_to_twain(const char* val) - { - const char* hz = to_default_language(val, NULL); - if (strcmp(hz, OPTION_VALUE_WGFX_90) == 0) - return 90.0f; - else if (strcmp(hz, OPTION_VALUE_WGFX_180) == 0) - return 180.0f; - else if (strcmp(hz, OPTION_VALUE_WGFX__90) == 0) - return 270.0f; - else if (strcmp(hz, OPTION_VALUE_WGFX_0) == 0) - return .0f; - else - return AUTO_MATIC_ROTATE; - } - - struct - { - const char* normal; - const char* lateral; - }g_lateral_map[] = - { {OPTION_VALUE_ZZCC_A4, OPTION_VALUE_ZZCC_A4HX} - , {OPTION_VALUE_ZZCC_16K, OPTION_VALUE_ZZCC_16KHX} - , {OPTION_VALUE_ZZCC_A5, OPTION_VALUE_ZZCC_A5HX} - , {OPTION_VALUE_ZZCC_A6, OPTION_VALUE_ZZCC_A6HX} - , {OPTION_VALUE_ZZCC_B5, OPTION_VALUE_ZZCC_B5HX} - , {OPTION_VALUE_ZZCC_B6, OPTION_VALUE_ZZCC_B6HX} - , {OPTION_VALUE_ZZCC_Letter, OPTION_VALUE_ZZCC_LetterHX} - }; - - const char* paper_from_twain(int val) - { - VALUE_FROM_TWAIN(g_paper_map, val); - - return NULL; - } - int paper_to_twain(const char* val) - { - VALUE_TO_TWAIN(g_paper_map, val); - - return -1; - } - const char* switch_paper_lateral(const char* val) - { - const char* hz = to_default_language(val, NULL); - for (int i = 0; i < _countof(g_lateral_map); ++i) - { - if (strcmp(g_lateral_map[i].normal, hz) == 0) - return from_default_language(g_lateral_map[i].lateral, NULL); - else if (strcmp(g_lateral_map[i].lateral, hz) == 0) - return from_default_language(g_lateral_map[i].normal, NULL); - } - - return NULL; - } - bool is_paper_lateral(const char* val) - { - const char* hz = to_default_language(val, NULL); - for (int i = 0; i < _countof(g_lateral_map); ++i) - { - if (strcmp(g_lateral_map[i].lateral, hz) == 0) - return true; - } - - return false; - } - - const char* auto_color_type_from_twain(int val) - { - VALUE_FROM_TWAIN(g_color_mode_map, val); - - return from_default_language(OPTION_VALUE_YSMS_24WCS, NULL); - } - int auto_color_type_to_twain(const char* val) - { - VALUE_TO_TWAIN(g_color_mode_map, val); - - return -1; - } - - const char* sharpen_from_twain(int val) - { - VALUE_FROM_TWAIN(g_sharpen_map, val); - - return from_default_language(OPTION_VALUE_RHYMH_W, NULL); - } - int sharpen_to_twain(const char* val) - { - VALUE_TO_TWAIN(g_sharpen_map, val); - - return SHARPEN_NONE; - } - - struct { - int twain; - int sane; - } - g_compression_map[] = { {0, SANE_COMPRESSION_NONE} - , {5, SANE_COMPRESSION_GROUP4} - } - ; -#define INT_FROM_TWAIN(arr, val) \ - for (int i = 0; i < _countof(arr); ++i) \ - { \ - if (arr[i].twain == val) \ - return arr[i].sane; \ - } -#define INT_TO_TWAIN(arr, val) \ - for (int i = 0; i < _countof(arr); ++i) \ - { \ - if (arr[i].sane == val) \ - return arr[i].twain; \ - } - - int compression_from_twain(int val) - { - INT_FROM_TWAIN(g_compression_map, val); - - return SANE_COMPRESSION_NONE; - } - int compression_to_twain(int val) - { - INT_TO_TWAIN(g_compression_map, val); - - return 0; - } - std::vector support_image_types(void) - { - std::vector it; - - it.push_back(SANE_IMAGE_TYPE_BMP); - it.push_back(SANE_IMAGE_TYPE_TIFF); - it.push_back(SANE_IMAGE_TYPE_JFIF); - - return it; - } -} - diff --git a/sane/sane_option_trans.h b/sane/sane_option_trans.h deleted file mode 100644 index 72dbac2..0000000 --- a/sane/sane_option_trans.h +++ /dev/null @@ -1,41 +0,0 @@ -// utilities for transfroming options between TWAIN and sane ... -// -// Date: 2022-04-14 -// - -#pragma once - -#include "s2t_api.h" - -namespace sane_opt_trans -{ - const char* color_mode_from_twain(int val); - int color_mode_to_twain(const char* val); - - const char* multiout_value_from_twain(int val); - int multiout_value_to_twain(const char* val); - - const char* filter_enhance_value_from_twain(int val, bool filter); - int filter_enhance_value_to_twain(const char* val, bool* is_filter); - - const char* text_direction_from_twain(float val); - float text_direction_to_twain(const char* val); - - const char* paper_from_twain(int val); - int paper_to_twain(const char* val); - - const char* switch_paper_lateral(const char* val); - bool is_paper_lateral(const char* val); - - const char* auto_color_type_from_twain(int val); - int auto_color_type_to_twain(const char* val); - - const char* sharpen_from_twain(int val); - int sharpen_to_twain(const char* val); - - int compression_from_twain(int val); - int compression_to_twain(int val); - - std::vector support_image_types(void); -} - diff --git a/sane/scanned_img.cpp b/sane/scanned_img.cpp deleted file mode 100644 index e46c3f3..0000000 --- a/sane/scanned_img.cpp +++ /dev/null @@ -1,795 +0,0 @@ -#include "scanned_img.h" - -#include -#include -#pragma comment(lib, "Shlwapi.lib") - -#include "../../code_device/hgsane/sane_hg_mdw.h" -#include "../../sdk/include/lang/app_language.h" - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -namespace local_trans -{ - std::string u2a(const wchar_t* u, UINT cp) - { - std::string a(""); - - if (u) - { - char * ansi = NULL; - int len = 0; - - len = WideCharToMultiByte(cp, 0, u, lstrlenW(u), NULL, 0, NULL, NULL); - ansi = new char[len + 2]; - len = WideCharToMultiByte(cp, 0, u, lstrlenW(u), ansi, len, NULL, NULL); - ansi[len--] = 0; - a = ansi; - delete[] ansi; - } - - return std::move(a); - } - std::wstring a2u(const char* asc, UINT cp) - { - std::wstring u(L""); - - if (asc) - { - wchar_t *buf = NULL; - int len = 0; - - len = MultiByteToWideChar(cp, 0, asc, lstrlenA(asc), NULL, 0); - buf = new wchar_t[len + 2]; - len = MultiByteToWideChar(cp, 0, asc, lstrlenA(asc), buf, len); - buf[len--] = 0; - u = buf; - delete[] buf; - } - - return std::move(u); - } - - std::wstring lang_trans_between_hz936(const wchar_t* in, bool from_hz) - { - std::string a(u2a(in, CP_UTF8)); - - if (from_hz) - a = from_default_language(a.c_str(), nullptr); - else - a = to_default_language(a.c_str(), nullptr); - - return std::move(a2u(a.c_str(), CP_UTF8)); - } - const char* __stdcall lang_trans_between_hz936(const char* in, bool from_hz, void* param) - { - return from_hz ? from_default_language(in, nullptr) : to_default_language(in, nullptr); - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class refer -refer::refer() : ref_(1) -{} -refer::~refer() -{} - -COM_API_IMPLEMENT(refer, long, add_ref(void)) -{ - return InterlockedIncrement(&ref_); -} -COM_API_IMPLEMENT(refer, long, release(void)) -{ - long ref = InterlockedDecrement(&ref_); - - if (ref == 0) - delete this; - - return ref; -} - - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class mapping_buf -const unsigned int max_mem_block = 2 * 1024 * 1024; -extern void __stdcall log_info(const wchar_t* info, int level); - -mapping_buf::mapping_buf() : bytes_(0), offset_(0), mapped_bytes_(0), map_(NULL), buf_(NULL), file_(""), rmv_file_(true), page_size_(0), is_mem_(false) -{ - SYSTEM_INFO si = { 0 }; - - GetSystemInfo(&si); - page_size_ = si.dwPageSize; - map_unit_ = si.dwAllocationGranularity; -} -mapping_buf::~mapping_buf() -{ - close(); -} - -void mapping_buf::init_map(const char* file, unsigned long long size) -{ - HANDLE f = INVALID_HANDLE_VALUE; - - if (size) - { - f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (f != INVALID_HANDLE_VALUE) - { - unsigned long long total = size - 1; - LONG* p32 = (LONG*)&total; - *p32 = SetFilePointer(f, *p32, p32 + 1, FILE_BEGIN); - total++; - if (total == size) - { - DWORD wrote = 1; - WriteFile(f, "\0", 1, &wrote, NULL); - map_ = CreateFileMapping(f, NULL, PAGE_READWRITE, p32[1], p32[0], NULL); - } - CloseHandle(f); - if (!map_) - DeleteFileA(file); - } - - { - std::wstring info(local_trans::a2u(file)); - wchar_t buf[80] = { 0 }; - - swprintf_s(buf, _countof(buf) - 1, L"Mapping %u bytes to file: ", size); - log_info((buf + info + L"\r\n").c_str(), 0); - } - } - else - { - f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (f != INVALID_HANDLE_VALUE) - { - DWORD* p32 = (DWORD*)&size; - *p32 = GetFileSize(f, p32 + 1); - map_ = CreateFileMapping(f, NULL, PAGE_READWRITE, p32[1], p32[0], NULL); - CloseHandle(f); - } - } - - if (map_) - { - bytes_ = size; - file_ = file; - buffer(0, NULL); - if (!map_) - close(); - } -} -void mapping_buf::close(void) -{ - if (buf_) - { - if (is_mem_) - delete[] buf_; - else - UnmapViewOfFile(buf_); - } - buf_ = NULL; - if (map_) - CloseHandle(map_); - map_ = NULL; - if (rmv_file_ && file_.length()) - DeleteFileA(file_.c_str()); - file_ = ""; - bytes_ = offset_ = 0; - mapped_bytes_ = 0; - rmv_file_ = true; - is_mem_ = false; -} -void mapping_buf::map(void) -{ - DWORD* off = (DWORD*)&offset_; - - buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, off[1], off[0], mapped_bytes_); - if (!buf_) - { - DWORD err = GetLastError(); - mapped_bytes_ /= map_unit_; - mapped_bytes_ *= map_unit_; - while (mapped_bytes_ > map_unit_) - { - buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, off[1], off[0], mapped_bytes_); - if (buf_) - break; - mapped_bytes_ /= 2; - } - if (!buf_) - mapped_bytes_ = 0; - } -} -void mapping_buf::set_buffer(unsigned char*& buf, unsigned long long off, unsigned int* bytes) -{ - buf = buf_ + (off - offset_); - if (bytes) - *bytes = mapped_bytes_ - (unsigned int)(off - offset_); -} - -unsigned char* mapping_buf::allocate(const wchar_t* file, unsigned long long size, bool force_file) -{ - close(); - - std::string ansi(local_trans::u2a(file)); - if (force_file || size >= 100 * 1024 * 1024 || PathFileExistsW(file)) - { - init_map(ansi.c_str(), size); - } - else - { - try - { - buf_ = new unsigned char[(unsigned int)size]; - is_mem_ = true; - bytes_ = size; - mapped_bytes_ = (unsigned int)size; - } - catch (...) - { - is_mem_ = false; - init_map(ansi.c_str(), size); - } - } - - return buf_; -} -unsigned char* mapping_buf::buffer(unsigned long long off, unsigned int* bytes) -{ - unsigned int size = bytes ? *bytes : 1 * 1024 * 1024 * 1024; - unsigned char* buf = NULL; - - if (size > bytes_ - offset_) - size = (unsigned int)(bytes_ - offset_); - - if (buf_ && off >= offset_ && size + (off - offset_) <= mapped_bytes_) - { - set_buffer(buf, off, bytes); - } - else if (!is_mem_) - { - if (off < bytes_) - { - if (buf_) - UnmapViewOfFile(buf_); - - offset_ = off / map_unit_ * map_unit_; - mapped_bytes_ = (unsigned int)(bytes_ - offset_); - map(); - if (buf_) - set_buffer(buf, off, bytes); - } - } - - return buf; -} -bool mapping_buf::save(const void* data, size_t* bytes, unsigned long long off) -{ - unsigned int len = *bytes, total = 0; - unsigned char* buf = buffer(off, &len); - bool ret = false; - const char* src = (const char*)data; - - while (buf) - { - if (len >= *bytes - total) - { - memcpy(buf, src, *bytes - total); - total = *bytes; - ret = true; - break; - } - memcpy(buf, src, len); - total += len; - off += len; - src += len; - len = *bytes - total; - buf = buffer(off, &len); - } - *bytes = total; - - return ret; -} -bool mapping_buf::save(unsigned long long off, mapping_buf* mbuf, unsigned long long src_off) -{ - size_t len = (unsigned int)(mbuf->bytes() - src_off); - unsigned char* buf = mbuf->buffer(src_off, (unsigned int*)&len); - bool ret = false; - - while (buf && save(buf, &len, off)) - { - off += len; - src_off += len; - if (src_off >= mbuf->bytes()) - { - ret = true; - break; - } - len = (unsigned int)(mbuf->bytes() - src_off); - buf = mbuf->buffer(src_off, (unsigned int*)&len); - } - - return ret; -} -int mapping_buf::read(void* buf, size_t* bytes, unsigned long long off) -{ - if (!bytes) - return SCANNER_ERR_INVALID_PARAMETER; - - unsigned int len = *bytes, total = 0; - unsigned char *src = buffer(off, &len), - *dst = (unsigned char*)buf; - int ret = SCANNER_ERR_OUT_OF_RANGE; - - while (src) - { - if (len >= *bytes - total) - { - memcpy(dst, src, *bytes - total); - total = *bytes; - ret = SCANNER_ERR_OK; - break; - } - - memcpy(dst, src, len); - total += len; - off += len; - len = *bytes - total; - src = buffer(off, &len); - } - *bytes = total; - - return ret; -} -void mapping_buf::unmap() -{ - if (!is_mem_) - { - if (buf_) - UnmapViewOfFile(buf_); - buf_ = NULL; - offset_ = 0; - mapped_bytes_ = 0; - } -} -void mapping_buf::set_remove_file_when_destroyed(bool rmv) -{ - rmv_file_ = rmv; -} -const char* mapping_buf::file(void) -{ - return is_mem_ ? "" : file_.c_str(); -} -unsigned long long mapping_buf::bytes(void) -{ - return bytes_; -} -unsigned long long mapping_buf::offset(void) -{ - return offset_; -} -unsigned int mapping_buf::mapped_bytes(void) -{ - return mapped_bytes_; -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class scanned_img -scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, int dpi - , const wchar_t* tmp_file, twain_xfer xfer - , SANE_FinalImgFormat *fmt) : head_(head), dpi_(dpi), header_size_(0), file_(tmp_file ? tmp_file : L"") - , dev_(dev), status_(SANE_Image_Statu_OK) -{ - if (fmt) - fmt_ = *fmt; - else - { - fmt_.img_format = SANE_IMAGE_TYPE_BMP; - fmt_.detail = 0; - } - - size_t bytes = line_bytes() * height(); - std::string h(file_header(fmt_.img_format, (float)dpi, xfer)); - unsigned char* dst = NULL; - bool ok = false; - - data_ = new mapping_buf(); - header_size_ = h.length(); - dst = data_->allocate(tmp_file, bytes + h.length()); - if (dst) - { - unsigned long long off = 0, total = 0; - bytes = h.length(); - if (data_->save(h.c_str(), &bytes, off)) - { - unsigned int len = line_bytes(); - unsigned long long line = line_bytes(); - - if (xfer == TWAIN_XFER_Memory) - line *= -1; - else - off = data_->bytes() - line; - dst = data_->buffer(off, &len); - - int want_to_read = head_.bytes_per_line, rcv = 0, dif = line_bytes() - head_.bytes_per_line; - while (dst) - { - int r = want_to_read > (int)(len) - rcv ? (int)(len)- rcv : want_to_read; - int ret = hg_sane_middleware::instance()->read(dev, dst + rcv, &r); - total += r; - if (ret != SANE_STATUS_GOOD) - break; - - want_to_read -= r; - rcv += r; - if (want_to_read == 0) - { - want_to_read = head_.bytes_per_line; - off -= line; - len = line_bytes(); - rcv = 0; - dst = data_->buffer(off, &len); - total += dif; - } - else - { - len = want_to_read; - dst = data_->buffer(off + rcv, &len); - } - } - ok = total + h.length() + dif == data_->bytes(); - } - } - do_result(ok, xfer); -} -scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file - , twain_xfer xfer, SANE_FinalImgFormat* fmt) : head_(head), dpi_(dpi), header_size_(0) - , file_(tmp_file ? tmp_file : L""), dev_(dev), status_(SANE_Image_Statu_OK) -{ - if (fmt) - fmt_ = *fmt; - else - { - fmt_.img_format = SANE_IMAGE_TYPE_BMP; - fmt_.detail = 0; - } - - size_t bytes = line_bytes() * head.lines; - std::string h(file_header(fmt_.img_format, (float)dpi, xfer)); - unsigned char* dst = NULL, *src = (unsigned char*)data; - bool ok = false; - - header_size_ = h.length(); - data_ = new mapping_buf(); - bytes += header_size_; - dst = data_->allocate(tmp_file, bytes); - bytes = h.length(); - if (dst && data_->save(h.c_str(), &bytes, 0)) - { - unsigned long long off = bytes, line_l = line_bytes(); - unsigned int buf_len = line_bytes(), row = 0; - if (xfer == TWAIN_XFER_Memory) - line_l *= -1; - else - off = data_->bytes() - line_l; - for (; row < (unsigned int)head.lines; ++row) - { - bytes = head.bytes_per_line; - if (!data_->save(src, &bytes, off)) - break; - off -= line_l; - src += head.bytes_per_line; - } - ok = row == head.lines; - } - do_result(ok, xfer); -} -scanned_img::~scanned_img() -{ - if (data_) - delete data_; -} - -void scanned_img::set_image_status(SANE_Image_Statu status) -{ - status_ = status; -} - -std::string scanned_img::file_header(SANE_ImageType type, float resolution, twain_xfer xfer) -{ - std::string h(""); - - if (type == SANE_IMAGE_TYPE_BMP && xfer != TWAIN_XFER_Memory) - { - BITMAPINFOHEADER bih = { 0 }; - int pal_size = 0; - - bih.biSize = sizeof(bih); - bih.biWidth = width(); - bih.biBitCount = depth(); - bih.biSizeImage = line_bytes() * height(); - bih.biPlanes = 1; - bih.biHeight = height(); - bih.biCompression = BI_RGB; - bih.biXPelsPerMeter = bih.biYPelsPerMeter = (LONG)(resolution * 39.37f + .5f); - - if (bih.biBitCount == 1) - pal_size = 2 * sizeof(int); - else if (bih.biBitCount == 8) - pal_size = 256 * sizeof(int); - - if (xfer == TWAIN_XFER_File) - { - BITMAPFILEHEADER fh = { 0 }; - fh.bfType = MAKEWORD('B', 'M'); - fh.bfSize = sizeof(fh) + bih.biSizeImage + sizeof(bih) + pal_size; - fh.bfOffBits = sizeof(fh) + sizeof(bih) + pal_size; - - h = std::string((char*)&fh, sizeof(fh)); - } - - h += std::string((char*)&bih, sizeof(bih)); - if (bih.biBitCount == 1) - { - int pal[] = { 0, 0x0ffffff }; - h += std::string((char*)pal, pal_size); - } - else if (bih.biBitCount == 8) - { - static unsigned int g_bmp8_pallete[256] = { 0 }; - if (g_bmp8_pallete[1] == 0) - { - for (int i = 1; i < _countof(g_bmp8_pallete); ++i) - g_bmp8_pallete[i] = MAKELONG(MAKEWORD(i, i), MAKEWORD(i, 0)); - } - h += std::string((char*)g_bmp8_pallete, pal_size); - } - } - - return h; -} -void scanned_img::do_result(bool ok, twain_xfer xfer) -{ - if (ok) - { - if (fmt_.img_format == SANE_IMAGE_TYPE_BMP && - fmt_.compress.compression == SANE_COMPRESSION_GROUP4 && - xfer == TWAIN_XFER_Memory) - { - // convert to black-white ... - std::string head(file_header(SANE_IMAGE_TYPE_BMP, (float)dpi_, TWAIN_XFER_File)); - size_t size = head.length(); - mapping_buf* buf = new mapping_buf(); - std::wstring file(file_ + L".tmp"); - unsigned long long off = 0; - - if (buf->allocate(file.c_str(), size + data_->bytes(), true) && - buf->save(head.c_str(), &size, off)) - { - if (buf->save(size, data_)) - { - SANE_ImageFormatConvert conv; - std::string sf(local_trans::u2a(file.c_str())); - - buf->unmap(); - conv.src.data = sf.c_str(); - conv.src.data_len = sf.length(); - conv.src.fmt.img_format = SANE_IMAGE_TYPE_BMP; - conv.src.fmt.compress.compression = SANE_COMPRESSION_NONE; - conv.src.is_file = SANE_TRUE; - - conv.dst.data = NULL; - conv.dst.data_len = 0; - conv.dst.fmt.img_format = SANE_IMAGE_TYPE_BMP; - conv.dst.fmt.compress.compression = SANE_COMPRESSION_GROUP4; - conv.dst.fmt.compress.detail = NULL; - conv.dst.is_file = false; - if (hg_sane_middleware::instance()->io_control(dev_, IO_CTRL_CODE_CONVERT_IMAGE_FORMAT, &conv, NULL) == SANE_STATUS_GOOD) - { - delete data_; - data_ = new mapping_buf(); - size = conv.dst.data_len; - data_->allocate(file_.c_str(), conv.dst.data_len); - data_->save(conv.dst.data, &size, 0); - hg_sane_middleware::instance()->io_control(dev_, IO_CTRL_CODE_FREE_MEMORY, (void*)conv.dst.data, &conv.dst.data_len); - head_.format = SANE_FRAME_GRAY; - head_.depth = 1; - head_.bytes_per_line = (head_.pixels_per_line + 7) / 8; - } - } - } - if (buf) - delete buf; - } - else if (fmt_.img_format == SANE_IMAGE_TYPE_BMP - && channel() == 3 - && xfer != TWAIN_XFER_Memory) - { - // swap RGB - swap_rgb(); - } - data_->unmap(); - } - else - { - delete data_; - data_ = NULL; - header_size_ = 0; - } -} -void scanned_img::swap_rgb(void) -{ - unsigned long long off = 0; - unsigned int line = line_bytes(), len = line; - unsigned char* dst = NULL; - - for (int i = 0; i < height(); ++i) - { - int l = head_.bytes_per_line, cur = 0; - - off = i * line + header_size_; - while (l > 0) - { - len = l; - dst = data_->buffer(off + cur, &len); - if (!dst) - break; - if (len > (unsigned int)l) - len = l; - len /= 3; - for (int pos = 0; pos < (int)len; ++pos) - { - unsigned char uc = dst[pos * 3 + 0]; - dst[pos * 3 + 0] = dst[pos * 3 + 2]; - dst[pos * 3 + 2] = uc; - } - l -= len * 3; - cur += len * 3; - } - if (!dst) - break; - } -} - -// IRef -COM_API_IMPLEMENT(scanned_img, long, add_ref(void)) -{ - return refer::add_ref(); -} -COM_API_IMPLEMENT(scanned_img, long, release(void)) -{ - return refer::release(); -} - -// IScanImg -COM_API_IMPLEMENT(scanned_img, int, width(void)) -{ - return head_.pixels_per_line; -} -COM_API_IMPLEMENT(scanned_img, int, line_bytes(void)) -{ - if (fmt_.img_format == SANE_IMAGE_TYPE_BMP && head_.depth >= 8) - return (head_.bytes_per_line + 3) / 4 * 4; - else - return head_.bytes_per_line; -} -COM_API_IMPLEMENT(scanned_img, int, height(void)) -{ - return head_.lines; -} -COM_API_IMPLEMENT(scanned_img, int, depth(void)) -{ - if (head_.format == SANE_FRAME_RGB) - return head_.depth * 3; - else - return head_.depth; - -} -COM_API_IMPLEMENT(scanned_img, int, channel(void)) -{ - return head_.format == SANE_FRAME_RGB ? 3 : 1; -} -COM_API_IMPLEMENT(scanned_img, int, dpi(void)) -{ - return dpi_; -} -COM_API_IMPLEMENT(scanned_img, SANE_Frame, type(void)) -{ - return head_.format; -} -COM_API_IMPLEMENT(scanned_img, unsigned int, bytes(void)) -{ - return data_ ? (unsigned int)data_->bytes() : 0; -} -COM_API_IMPLEMENT(scanned_img, unsigned int, header_size(void)) -{ - return header_size_; -} -COM_API_IMPLEMENT(scanned_img, unsigned char*, data(unsigned long long off, unsigned int* bytes)) -{ - return data_ ? data_->buffer(off, bytes) : NULL; -} -COM_API_IMPLEMENT(scanned_img, int, read(void* buf, size_t* bytes, unsigned long long off)) -{ - return data_ ? data_->read(buf, bytes, off) : SCANNER_ERR_NO_DATA; -} - -COM_API_IMPLEMENT(scanned_img, const char*, file(void)) -{ - if (data_) - return data_->file(); - else - return ""; -} -COM_API_IMPLEMENT(scanned_img, void, keep_file(bool keep)) -{ - if (data_) - data_->set_remove_file_when_destroyed(!keep); -} -COM_API_IMPLEMENT(scanned_img, void, copy_header(SANE_Parameters* head)) -{ - *head = head_; -} -COM_API_IMPLEMENT(scanned_img, int, image_status(void)) -{ - return status_; -} - - - - - - - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class safe_img_queue -safe_img_queue::safe_img_queue() -{} -safe_img_queue::~safe_img_queue() -{ - clear(); -} - -void __stdcall safe_img_queue::access_image(scanned_img* img) -{ - img->add_ref(); -} -void __stdcall safe_img_queue::free_image(scanned_img* img) -{ - img->release(); -} - -bool safe_img_queue::get_header(SANE_Parameters* header, size_t* bytes, int* dpi) -{ - scanned_img *img = take(false, &safe_img_queue::access_image); - bool ok = false; - - if (bytes) - *bytes = 0; - if (img) - { - if(header) - img->copy_header(header); - if(bytes) - *bytes = img->bytes(); - if (dpi) - *dpi = img->dpi(); - ok = true; - img->release(); - } - - return ok; -} -void safe_img_queue::clear() -{ - safe_queue::clear(&safe_img_queue::free_image); -} - diff --git a/sane/scanned_img.h b/sane/scanned_img.h deleted file mode 100644 index 4beb9bd..0000000 --- a/sane/scanned_img.h +++ /dev/null @@ -1,201 +0,0 @@ -#pragma once -#include "s2t_api.h" -#include -#include - -class refer : public IRef -{ - volatile long ref_; - -protected: - refer(); - virtual ~refer(); - - // IRef -public: - COM_API_OVERRIDE(long, add_ref(void)); - COM_API_OVERRIDE(long, release(void)); -}; - -class mapping_buf -{ - unsigned long long bytes_; - unsigned long long offset_; - unsigned int page_size_; - unsigned int map_unit_; - unsigned int mapped_bytes_; - HANDLE map_; - bool is_mem_; - unsigned char* buf_; - std::string file_; - bool rmv_file_; - - void init_map(const char* file, unsigned long long size); - void close(void); - void map(void); - void set_buffer(unsigned char*& buf, unsigned long long off, unsigned int* bytes); - -public: - mapping_buf(); - ~mapping_buf(); - -public: - unsigned char* allocate(const wchar_t* file, unsigned long long size = 0, bool force_file = false); - unsigned char* buffer(unsigned long long off, unsigned int* bytes); - bool save(const void* data, size_t* bytes, unsigned long long off); - bool save(unsigned long long off, mapping_buf* mbuf, unsigned long long src_off = 0); - int read(void* buf, size_t* bytes, unsigned long long off); - void unmap(); - void set_remove_file_when_destroyed(bool rmv); - const char* file(void); - unsigned long long bytes(void); - unsigned long long offset(void); - unsigned int mapped_bytes(void); -}; -class scanned_img : public IScanImg, virtual public refer -{ - SANE_Parameters head_; - mapping_buf* data_; - int dpi_; - SANE_Handle dev_; - std::wstring file_; - unsigned int header_size_; - SANE_FinalImgFormat fmt_; - - SANE_Image_Statu status_; - - std::string file_header(SANE_ImageType type, float resolution, twain_xfer xfer); - void do_result(bool ok, twain_xfer xfer); - void swap_rgb(void); - -public: - scanned_img(SANE_Handle dev, SANE_Parameters head, int dpi, const wchar_t* tmp_file - , twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL); - scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file - , twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL); - - void set_image_status(SANE_Image_Statu status); - -protected: - ~scanned_img(); - - // IRef -public: - COM_API_OVERRIDE(long, add_ref(void)); - COM_API_OVERRIDE(long, release(void)); - - // IScanImg -public: - COM_API_OVERRIDE(int, width(void)); - COM_API_OVERRIDE(int, line_bytes(void)); - COM_API_OVERRIDE(int, height(void)); - COM_API_OVERRIDE(int, depth(void)); - COM_API_OVERRIDE(int, channel(void)); - COM_API_OVERRIDE(int, dpi(void)); - COM_API_OVERRIDE(SANE_Frame, type(void)); - COM_API_OVERRIDE(unsigned int, bytes(void)); - COM_API_OVERRIDE(unsigned int, header_size(void)); - COM_API_OVERRIDE(unsigned char*, data(unsigned long long off, unsigned int* bytes)); - COM_API_OVERRIDE(int, read(void* buf, size_t* bytes, unsigned long long off = 0)); - COM_API_OVERRIDE(const char*, file(void)); - COM_API_OVERRIDE(void, keep_file(bool keep)); - COM_API_OVERRIDE(void, copy_header(SANE_Parameters* head)); - COM_API_OVERRIDE(int, image_status(void)); -}; - -template -class safe_queue -{ - typedef struct _t_and_size - { - size_t bytes; - T t; - }TNS; - std::mutex lock_; - std::vector queue_; - size_t bytes_; - T empty_; - -public: - safe_queue() : bytes_(0) - {} - virtual ~safe_queue() - {} - -public: - size_t count(size_t* bytes = NULL) - { - std::lock_guard lock(lock_); - - if (bytes) - *bytes = bytes_; - - return queue_.size(); - } - bool save(T v, size_t bytes) - { - std::lock_guard lock(lock_); - TNS tns = { bytes, v }; - - queue_.push_back(tns); - bytes_ += bytes; - - return true; - } - T take(bool remove = true, void(__stdcall* first)(T) = NULL) - { - std::lock_guard lock(lock_); - TNS t; - - if (queue_.size()) - { - t = queue_[0]; - if (remove) - { - queue_.erase(queue_.begin()); - bytes_ -= t.bytes; - } - if (first) - first(t.t); - } - else - t.t = empty_; - - return t.t; - } - void clear(void(__stdcall* tfree)(T) = NULL) - { - std::lock_guard lock(lock_); - - if (tfree) - { - for (auto& v : queue_) - tfree(v.t); - } - queue_.clear(); - bytes_ = 0; - } -}; - -class safe_img_queue : public safe_queue -{ - static void __stdcall access_image(scanned_img* img); - static void __stdcall free_image(scanned_img* img); - -public: - safe_img_queue(); - ~safe_img_queue(); - -public: - bool get_header(SANE_Parameters* header, size_t* bytes = NULL, int *dpi = NULL); - void clear(); -}; - -namespace local_trans -{ - std::string u2a(const wchar_t* unic, UINT cp = CP_ACP); - std::wstring a2u(const char* asc, UINT cp = CP_ACP); - - std::wstring lang_trans_between_hz936(const wchar_t* in, bool from_hz = true); - const char* __stdcall lang_trans_between_hz936(const char* in, bool from_hz, void* param); -} diff --git a/sane/scanner.cpp b/sane/scanner.cpp deleted file mode 100644 index bbec3c7..0000000 --- a/sane/scanner.cpp +++ /dev/null @@ -1,3239 +0,0 @@ -#include "scanner.h" - -#include -#include // for PathFileExistsW -#include "../sdk/hginclude/huagaoxxx_warraper_ex.h" -#include -#include "../../code_device/hgsane/sane_hg_mdw.h" -#include "sane_option_trans.h" -#include -#include -#include "DlgIndicator.h" -#include "DlgSetting.h" -#include "gb_json.h" -#include "../../sdk/include/lang/app_language.h" -#include - -#pragma comment(lib, "Shlwapi.lib") - - -static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt); - -#define SET_SANE_OPT_ID(id, id_name, name, val, extension) \ - if(strcmp(SANE_STD_OPT_NAME_##name, val) == 0) \ - { \ - id_name##_id_ = id; \ - extension(id); \ - } - - -#ifdef EXPORT_SANE_API -__declspec(dllexport) -#else -__declspec(dllimport) -#endif -void __stdcall log_info(const wchar_t* info, int level); - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// callback -extern "C" -{ - extern SANE_Status inner_sane_init(SANE_Int* version_code, SANE_Auth_Callback authorize); - extern void inner_sane_exit(void); - extern SANE_Status inner_sane_get_devices(const SANE_Device*** device_list, SANE_Bool local_only); - extern SANE_Status inner_sane_open(SANE_String_Const devicename, SANE_Handle* handle); - extern void inner_sane_close(SANE_Handle handle); - extern const SANE_Option_Descriptor* inner_sane_get_option_descriptor(SANE_Handle handle, SANE_Int option); - extern SANE_Status inner_sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void* value, SANE_Int* info); - extern SANE_Status inner_sane_get_parameters(SANE_Handle handle, SANE_Parameters* params); - extern SANE_Status inner_sane_start(SANE_Handle handle); - extern SANE_Status inner_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length); - extern void inner_sane_cancel(SANE_Handle handle); - extern SANE_Status inner_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking); - extern SANE_Status inner_sane_get_select_fd(SANE_Handle handle, SANE_Int* fd); - extern SANE_String_Const inner_sane_strstatus(SANE_Status status); - - extern SANE_Status inner_sane_init_ex(SANE_Int* version_code, sane_callback cb, void* param); - extern SANE_Status inner_sane_io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len); - extern const char* inner_sane_err_desc(SANE_Status err); -} - -namespace callback -{ - static std::mutex cb_lock_; - typedef struct _scanner_inst - { - SANE_Handle dev; - scanner* invoker; - - bool operator==(const SANE_Handle& h) - { - return dev == h; - } - bool operator==(const scanner* obj) - { - return invoker == obj; - } - }SCNINST; - std::vector g_scanner_instances; - - int sane_event_callback( // 注册回调的对象,需要保证该回调是多线程安全的 - SANE_Handle hdev // 产生事件的设备句柄 - , int code // 回调事件代码 - , void* data // 回调事件数据,根据事件代码有所不同,参照具体事件定义 - , unsigned int* len // 数据长度(字节),或者event_data的缓冲区长度,详细请看相应的事件代码 - , void* param // 用户自定义数据,与调用sane_init_ex传入时的保持一致 - ) // 返回值依不同的事件代码而定,通常为“0” - { - std::lock_guard lock(cb_lock_); - std::vector::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), hdev); - - if (it != g_scanner_instances.end()) - return it->invoker->handle_device_event(code, data, len); - else - { - wchar_t msg[218] = { 0 }; - swprintf_s(msg, _countof(msg) - 1, L"Lost device(0x%08X) when event(%u) occurs!\r\n", hdev, code); - log_info(msg, 0); - - return 0; - } - } - void reg_callback(SANE_Handle dev, scanner* invoker) - { - std::lock_guard lock(cb_lock_); - std::vector::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), dev); - if (it == g_scanner_instances.end()) - { - SCNINST inst; - - inst.dev = dev; - inst.invoker = invoker; - g_scanner_instances.push_back(inst); - } - else - it->invoker = invoker; - } - void unreg_callback(scanner* invoker) - { - std::lock_guard lock(cb_lock_); - std::vector::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), invoker); - if (it != g_scanner_instances.end()) - g_scanner_instances.erase(it); - } - - struct - { - const char* name; - const char* title; - }g_opts[] = { {SANE_STD_OPT_NAME_RESTORE , OPTION_TITLE_HFMRSZ} - , {SANE_STD_OPT_NAME_HELP , OPTION_TITLE_BZ} - , {SANE_STD_OPT_NAME_IS_MULTI_OUT , OPTION_TITLE_DLSC} - , {SANE_STD_OPT_NAME_MULTI_OUT_TYPE , OPTION_TITLE_DLSCLX} - , {SANE_STD_OPT_NAME_COLOR_MODE , OPTION_TITLE_YSMS} - , {SANE_STD_OPT_NAME_BINARY_THRESHOLD , OPTION_TITLE_HBTXYZ} - , {SANE_STD_OPT_NAME_REVERSE_01 , OPTION_TITLE_HBTXFSSC} - , {SANE_STD_OPT_NAME_FILTER , OPTION_TITLE_HDHHBTX_CSYZQ} - , {SANE_STD_OPT_NAME_RID_MULTIOUT_RED , OPTION_TITLE_24WCSTX_DLSCCH} - , {SANE_STD_OPT_NAME_RID_ANSWER_SHEET_RED , OPTION_TITLE_24WCSTX_DTKCH} - , {SANE_STD_OPT_NAME_ERASE_BACKGROUND , OPTION_TITLE_BJYC} - , {SANE_STD_OPT_NAME_BKG_COLOR_RANGE , OPTION_TITLE_BJSCFDFW} - , {SANE_STD_OPT_NAME_SHARPEN , OPTION_TITLE_RHYMH} - , {SANE_STD_OPT_NAME_RID_MORR , OPTION_TITLE_QCMW} - , {SANE_STD_OPT_NAME_RID_GRID , OPTION_TITLE_CWW} - , {SANE_STD_OPT_NAME_ERROR_EXTENSION , OPTION_TITLE_CWKS} - , {SANE_STD_OPT_NAME_NOISE_OPTIMIZE , OPTION_TITLE_HBTXZDYH} - , {SANE_STD_OPT_NAME_NOISE_SIZE , OPTION_TITLE_ZDYHCC} - , {SANE_STD_OPT_NAME_PAPER , OPTION_TITLE_ZZCC} - , {SANE_STD_OPT_NAME_CUSTOM_AREA , OPTION_TITLE_ZDYSMQY} - , {SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT , OPTION_TITLE_SMQYZCmm} - , {SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT , OPTION_TITLE_SMQYYCmm} - , {SANE_STD_OPT_NAME_CUSTOM_AREA_TOP , OPTION_TITLE_SMQYSCmm} - , {SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM , OPTION_TITLE_SMQYXCmm} - , {SANE_STD_OPT_NAME_SIZE_CHECK , OPTION_TITLE_CCJC} - , {SANE_STD_OPT_NAME_PAGE , OPTION_TITLE_SMYM} - , {SANE_STD_OPT_NAME_DISCARD_BLANK_SENS , OPTION_TITLE_TGKBYLMD} - , {SANE_STD_OPT_NAME_RESOLUTION , OPTION_TITLE_FBL} - , {SANE_STD_OPT_NAME_TIME_TO_SLEEP , OPTION_TITLE_XMSJ} - , {SANE_STD_OPT_NAME_IMAGE_QUALITY , OPTION_TITLE_HZ} - , {SANE_STD_OPT_NAME_EXCHANGE ,OPTION_TITLE_JHZFM} - , {SANE_STD_OPT_NAME_SPLIT ,OPTION_TITLE_TXCF } - , {SANE_STD_OPT_NAME_ANTI_SKEW , OPTION_TITLE_ZDJP} - , {SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA , OPTION_TITLE_QYSDQX} - , {SANE_STD_OPT_NAME_GAMMA , OPTION_TITLE_JMZ} - , {SANE_STD_OPT_NAME_BRIGHTNESS , OPTION_TITLE_LDZ} - , {SANE_STD_OPT_NAME_CONTRAST , OPTION_TITLE_DBD} - , {SANE_STD_OPT_NAME_IS_PHOTO_MODE , OPTION_TITLE_ZPMS} - , {SANE_STD_OPT_NAME_ERASE_BLACK_FRAME , OPTION_TITLE_XCHK} - , {SANE_STD_OPT_NAME_DARK_SAMPLE , OPTION_TITLE_SSYZ} - , {SANE_STD_OPT_NAME_THRESHOLD , OPTION_TITLE_YZ} - , {SANE_STD_OPT_NAME_ANTI_NOISE_LEVEL , OPTION_TITLE_BJKZDJ} - , {SANE_STD_OPT_NAME_MARGIN , OPTION_TITLE_BYSJ} - , {SANE_STD_OPT_NAME_FILL_BKG_MODE , OPTION_TITLE_BJTCFS} - , {SANE_STD_OPT_NAME_IS_ANTI_PERMEATE , OPTION_TITLE_FZST} - , {SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL , OPTION_TITLE_FZSTDJ} - , {SANE_STD_OPT_NAME_RID_HOLE_L , OPTION_TITLE_CKYCZC} - , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_L , OPTION_TITLE_ZCCKSSFWZFMBL} - , {SANE_STD_OPT_NAME_RID_HOLE_R , OPTION_TITLE_CKYCYC} - , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_R , OPTION_TITLE_YCCKSSFWZFMBL} - , {SANE_STD_OPT_NAME_RID_HOLE_T , OPTION_TITLE_CKYCSC} - , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_T , OPTION_TITLE_SCCKSSFWZFMBL} - , {SANE_STD_OPT_NAME_RID_HOLE_B , OPTION_TITLE_CKYCXC} - , {SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_B , OPTION_TITLE_XCCKSSFWZFMBL} - , {SANE_STD_OPT_NAME_IS_FILL_COLOR , OPTION_TITLE_SCTC} - , {SANE_STD_OPT_NAME_IS_ULTROSONIC_CHECK , OPTION_TITLE_CSBJC} - , {SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE , OPTION_TITLE_SZTPCL} - , {SANE_STD_OPT_NAME_IS_CHECK_STAPLE , OPTION_TITLE_ZDJC} - , {SANE_STD_OPT_NAME_SCAN_MODE , OPTION_TITLE_SMZS} - , {SANE_STD_OPT_NAME_SCAN_COUNT , OPTION_TITLE_SMSL} - , {SANE_STD_OPT_NAME_TEXT_DIRECTION , OPTION_TITLE_WGFX} - , {SANE_STD_OPT_NAME_IS_ROTATE_BKG_180 , OPTION_TITLE_BMXZ180} - , {SANE_STD_OPT_NAME_IS_CHECK_DOG_EAR , OPTION_TITLE_ZJJC} - , {SANE_STD_OPT_NAME_DOG_EAR_SIZE , OPTION_TITLE_ZJDX} - , {SANE_STD_OPT_NAME_IS_CHECK_ASKEW , OPTION_TITLE_WXJC} - , {SANE_STD_OPT_NAME_ASKEW_RANGE , OPTION_TITLE_WXRRD} - , {SANE_STD_OPT_NAME_FEED_STRENGTH , OPTION_TITLE_FZQD} - , {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , OPTION_TITLE_ZDFZQD} - , {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , OPTION_TITLE_JZSBL} - , {SANE_STD_OPT_NAME_WAIT_TO_SCAN , OPTION_TITLE_DZSM} - , {SANE_STD_OPT_NAME_FOLD_TYPE , OPTION_TITLE_DZMS} - , {SANE_STD_OPT_NAME_COLOR_CORRECTION , OPTION_TITLE_SPJZ} - }, - g_discard[] = { {SANE_STD_OPT_NAME_REVERSE_01 , "\351\273\221\347\231\275\345\233\276\345\203\217\345\217\215\350\211\262\350\276\223\345\207\272\357\274\210\346\255\243\345\270\270\351\242\234\350\211\262\344\270\272\357\274\2320-\351\273\221\350\211\262\357\274\2331-\347\231\275\350\211\262\357\274\211"} // 黑白图像反色输出(正常颜色为:0-黑色;1-白色) - , {SANE_STD_OPT_NAME_FILTER , "\347\201\260\345\272\246\346\210\226\351\273\221\347\231\275\345\233\276\345\203\217 - \351\231\244\350\211\262"} // 灰度或黑白图像 - 除色 - , {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // 自动搓纸强度 - , {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " 搓纸阈值" - }; - const char* option_title_2_name(const char* title) - { - while (*title == ' ') - title++; - - for (size_t i = 0; i < _countof(g_discard); ++i) - { - if (strcmp(title, g_discard[i].title) == 0) - return g_discard[i].name; - } - for (size_t i = 0; i < _countof(g_opts); ++i) - { - if (strcmp(title, g_opts[i].title) == 0) - return g_opts[i].name; - } - - return ""; - } - const char* __stdcall option_name_2_title(const char* name) - { - for (size_t i = 0; i < _countof(g_opts); ++i) - { - if (strcmp(name, g_opts[i].name) == 0) - return g_opts[i].title; - } - - return ""; - } - - static BOOL CALLBACK main_wnd(HWND hwnd, LPARAM param) - { - DWORD pid = 0; - - GetWindowThreadProcessId(hwnd, &pid); - if (pid != GetCurrentProcessId()) - return TRUE; - - if (((void**)param)[1] == NULL) - { - HWND parent = GetParent(hwnd); - while (IsWindow(parent)) - { - hwnd = parent; - parent = GetParent(hwnd); - } - parent = hwnd; - if (!IsWindowVisible(parent)) - return TRUE; - - RECT r = { 0 }; - GetWindowRect(parent, &r); - if (RECT_H(r) > 50 && RECT_W(r) > 50) - { - *(HWND*)param = parent; - - return FALSE; - } - } - else - { - wchar_t val[128] = { 0 }; - GetClassNameW(hwnd, val, _countof(val) - 1); - if (wcscmp(val, L"#32770")) - return TRUE; - - GetWindowTextW(hwnd, val, _countof(val) - 1); - if (*((std::wstring**)param)[1] == val) - { - *(HWND*)param = hwnd; - - return FALSE; - } - } - - return TRUE; - } - static HWND find_main_wnd(void) - { - HWND wnd[2] = { NULL }; - - EnumWindows(main_wnd, (LPARAM)wnd); - - return wnd[0]; - } - static DWORD WINAPI btm(LPVOID para) - { - std::wstring* title[2] = { NULL, (std::wstring*)para }; - - Sleep(100); - EnumWindows(main_wnd, (LPARAM)title); - if (IsWindow((HWND)title[0])) - { - RECT r = { 0 }; - GetWindowRect((HWND)title[0], &r); - SetWindowPos((HWND)title[0], HWND_TOPMOST, r.left, r.top, RECT_W(r), RECT_H(r), SWP_SHOWWINDOW | SWP_NOSENDCHANGING); - SetFocus((HWND)title[0]); - } - - delete title[1]; - - return 0; - } - static void bring_message_box_topmost(const wchar_t* title) - { - DWORD id = 0; - std::wstring* t(new std::wstring(title)); - HANDLE h = CreateThread(NULL, 0, btm, t, 0, &id); - - if (h) - CloseHandle(h); - else - delete t; - } - - static const char* __stdcall language_trans(const char* in, bool from_hz, void* param) - { - if (from_hz) - return from_default_language(in, nullptr); - else - return to_default_language(in, nullptr); - } - - - // UI ... - // - // events code, see SANE_Event - // - // callback events: SANE_EVENT_UI_CLOSE_CANCEL/SANE_EVENT_UI_CLOSE_NORMAL/SANE_EVENT_UI_SCAN_COMMAND/SANE_EVENT_UI_CLOSE_SETTING - // - // notify events: SANE_EVENT_WORKING - void*: unused, be NULL, flag - unused, be 0 - // SANE_EVENT_SCAN_FINISHED - void*: (utf8*)message, flag - error code (0 is success) - // SANE_EVENT_USB_DATA_RECEIVED- void* unused, be NULL, flag - unused, be 0 - // SANE_EVENT_IMAGE_OK - void* unused, be NULL, flag - unused, be 0 - int (*choose_scanner)(const std::vector& devs) = NULL; // blocked. return selected DEVQUE::id or -1 if user cancelled - void (*apply_current_config)(const char* dev_name, SANE_Handle device, LPSANEAPI api) = NULL; // 应用设备的当前配置 - void (*show_setting_ui)(SANE_Handle device, HWND parent, LPSANEAPI api, bool with_scan/*是否显示“扫描”按钮*/, std::function callback) = NULL; - void (*show_progress_ui)(HWND parent, std::function callback, std::function* notify) = NULL; - static void init_ui(void) - { - std::string root(hg_sane_middleware::sane_path()); - HMODULE mod = NULL; - - root += "HGTwainUI.dll"; - - mod = LoadLibraryExA(root.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - if (!mod) - { - std::wstring info(L"Load '" + local_trans::a2u(root.c_str(), CP_UTF8)); - - info += L"' failed: " + std::to_wstring(GetLastError()) + L"\r\n"; - - log_info(info.c_str(), 0); - } - else - { -#define GET_API(api) \ - proc = (FARPROC*)&api; \ - *proc = GetProcAddress(mod, #api); - - FARPROC* proc = NULL; - - GET_API(choose_scanner); - GET_API(apply_current_config); - GET_API(show_setting_ui); - GET_API(show_progress_ui); - } - } -} - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class scanner -scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BASE), prev_start_result_(SCANNER_ERR_NOT_START) - , dpi_(200), tmp_path_(L""), img_ind_(0) - , scanner_name_(L""), cfg_(NULL), is_ui_wait_img_(false), is_scanning_(false) - , scanner_ev_handler_(NULL), evh_param_(NULL), app_wnd_(NULL), user_cancel_(false) - , max_img_mem_(1 * 1024), twain_set_(false), ev_cnt_(0) -{ - sane_api_.sane_cancel_api = inner_sane_cancel; - sane_api_.sane_close_api = inner_sane_close; - sane_api_.sane_control_option_api = inner_sane_control_option; - sane_api_.sane_get_devices_api = inner_sane_get_devices; - sane_api_.sane_get_option_descriptor_api = inner_sane_get_option_descriptor; - sane_api_.sane_get_parameters_api = inner_sane_get_parameters; - sane_api_.sane_get_select_fd_api = inner_sane_get_select_fd; - sane_api_.sane_io_control_api = inner_sane_io_control; - sane_api_.sane_open_api = inner_sane_open; - sane_api_.sane_read_api = inner_sane_read; - sane_api_.sane_set_io_mode_api = inner_sane_set_io_mode; - sane_api_.sane_start_api = inner_sane_start; - sane_api_.sane_strstatus_api = inner_sane_strstatus; - - if (!callback::show_setting_ui) - { - cfg_ = new gb::scanner_cfg(); - cfg_->set_language_transform(&callback::language_trans, NULL); - } - - tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str()); - { - char* tmp = getenv("LOCALAPPDATA"); - - if (tmp) - { - tmp_path_ = local_trans::a2u(tmp) + L"\\"; - tmp_path_ += local_trans::a2u(PRODUCT_VENDOR) + L"Scan\\"; - CreateDirectoryW(tmp_path_.c_str(), NULL); - } - } - cfg_path_ = tmp_path_ + L"config"; - CreateDirectoryW(cfg_path_.c_str(), NULL); - cfg_path_ += L"\\"; - tmp_path_ += L"imgs"; - CreateDirectoryW(tmp_path_.c_str(), NULL); - tmp_path_ += L"\\"; - img_fmt_.img_format = SANE_IMAGE_TYPE_BMP; - img_fmt_.compress.compression = SANE_COMPRESSION_NONE; - - int mem_limit = GetPrivateProfileIntW(L"mem", L"max_img", 0, (cfg_path_ + L"debug.cfg").c_str()); - if (mem_limit > 0) - { - // this value is same as driver memory limit ... - max_img_mem_ = mem_limit; - } - err_ = open(); -} -scanner::~scanner() -{ - close(); - if (cfg_) - { - cfg_->release(); - cfg_ = NULL; - } -} - -bool scanner::is_belong_serial(int vid, int pid, SCANNERID serial) -{ - if (vid == PRODUCT_VENDOR_HG) - { - if (GET_SCANNER_VID(serial) == PRODUCT_VENDOR_HG) - { - if (GET_SCANNER_PID(serial) == 0x100) - { - return pid == 0x100 || pid == 0x139; - } - else if (GET_SCANNER_PID(serial) == 0x200) - { - return pid == 0x200 || pid == 0x239; - } - else if (GET_SCANNER_PID(serial) == 0x300) - { - return pid == 0x300 || pid == 0x302 || pid == 0x339; - } - else if (GET_SCANNER_PID(serial) == 0x400) - { - return pid == 0x400 || pid == 0x402 || pid == 0x439; - } - else if (GET_SCANNER_PID(serial) == 0x138 || - GET_SCANNER_PID(serial) == 0x238 || - GET_SCANNER_PID(serial) == 0x303 || - GET_SCANNER_PID(serial) == 0x404) // OEM_CANGTIAN - return true; - } - - return false; - } - else if (vid == PRODUCT_VENDOR_HG1) - { - return pid == 0x7823 && GET_SCANNER_VID(serial) == PRODUCT_VENDOR_HG && GET_SCANNER_PID(serial) == 0x200; - } - else if (vid == PRODUCT_VENDOR_HW) - { - return GET_SCANNER_VID(serial) == vid && GET_SCANNER_PID(serial) == pid; - } - else if (vid == PRODUCT_VENDOR_LSC) - { - if (GET_SCANNER_VID(serial) == PRODUCT_VENDOR_LSC) - { - if (GET_SCANNER_PID(serial) == 0x8420) - { - return pid == 0x8200 || pid == 0x8420 || pid == 0x8429; - } - else if (GET_SCANNER_PID(serial) == 0x8520) - { - return pid == 0x8520 || pid == 0x8529; - } - else if (GET_SCANNER_PID(serial) == 0x8620) - { - return pid == 0x8620 || pid == 0x8629; - } - else if (GET_SCANNER_PID(serial) == 0x8730) - { - return pid == 0x8730 || pid == 0x8739; - } - } - return false; - } - return true; -} -void scanner::get_scanner_name(SCANNERID id, std::vector& names) -{ - ScannerInfo* devs = NULL; - long count = 0; - - names.clear(); - if (hg_scanner_enum(devs, &count, true) == SCANNER_ERR_INSUFFICIENT_MEMORY) - { - count++; - devs = new ScannerInfo[count]; - memset(devs, 0, count * sizeof(*devs)); - if (hg_scanner_enum(devs, &count, true) == SCANNER_ERR_OK) - { - for (int i = 0; i < count; ++i) - { - if (scanner::is_belong_serial(devs[i].vid, devs[i].pid, id)) - { - names.push_back(devs[i].name); - } - } - } - delete[] devs; - } -} -value_type scanner::from_sane_type(SANE_Value_Type type) -{ - if (type == SANE_TYPE_BOOL) - return VAL_TYPE_BOOL; - else if (type == SANE_TYPE_INT) - return VAL_TYPE_INT; - else if (type == SANE_TYPE_FIXED) - return VAL_TYPE_FLOAT; - else if (type == SANE_TYPE_STRING) - return VAL_TYPE_STR; - else - return VAL_TYPE_NONE; -} -value_limit scanner::from_sane_constraint(SANE_Constraint_Type type) -{ - if (type == SANE_CONSTRAINT_RANGE) - return VAL_LIMIT_RANGE; - else if (type == SANE_CONSTRAINT_STRING_LIST || type == SANE_CONSTRAINT_WORD_LIST) - return VAL_LIMIT_ENUM; - else - return VAL_LIMIT_NONE; -} -int scanner::control_read_string(SANE_Handle hdev, int code, std::string& str) -{ - char* buf = NULL; - unsigned len = 0; - int err = hg_sane_middleware::instance()->io_control(hdev, code, buf, &len); - - str = ""; - if (err == SANE_STATUS_NO_MEM) - { - len += 4; - buf = new char[len]; - memset(buf, 0, len); - err = hg_sane_middleware::instance()->io_control(hdev, code, buf, &len); - if (err == SANE_STATUS_GOOD) - str = buf; - delete[] buf; - } - - return err; -} - -int __stdcall scanner::to_int(SANE_Int v) -{ - return v; -} -float __stdcall scanner::to_float(SANE_Fixed v) -{ - return (float)SANE_UNFIX(v); -} -void __stdcall scanner::ui_callback(int uev, void* sender, void* param) -{ - ((scanner*)param)->on_ui_event(uev, sender); -} -bool scanner::is_option_float(int sn, void* param) -{ - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor((SANE_Handle)param, (const void*)sn); - - if (desc) - return desc->type == SANE_TYPE_FIXED; - else - return false; -} -void __stdcall scanner::apply_scheme(gb::sane_config_schm* schm, void* param) -{ - ((scanner*)param)->apply_scheme(schm); -} - -// IRef -COM_API_IMPLEMENT(scanner, long, add_ref(void)) -{ - return refer::add_ref(); -} -COM_API_IMPLEMENT(scanner, long, release(void)) -{ - return refer::release(); -} - -void scanner::transport_config_file(void) -{ - size_t pos = scanner_name_.find(L" - "); - std::wstring pid(L"G"), old(L""); - - if (pos == std::wstring::npos) - return; - - pid += scanner_name_.substr(pos + 3); - if (scanner_name_.find(L"HUAGOSCAN ") != std::wstring::npos) - { - old = local_trans::lang_trans_between_hz936(L"\u534E\u9AD8\u626B\u63CF\u4EEA\u2014"); - } - else if (scanner_name_.find(L"LANXUMSCAN ") != std::wstring::npos) - { - old = local_trans::lang_trans_between_hz936(L"\u7ACB\u601D\u8FB0\u626B\u63CF\u4EEA\u2014"); - pid += L"S"; - } - old += pid; - if (PathFileExistsW((cfg_path_ + old).c_str())) - { - log_info((L"Rename config file '" + old + L"' to '" + scanner_name_.substr(0, pos) + L"'\r\n").c_str(), 0); - MoveFileW((cfg_path_ + old).c_str(), (cfg_path_ + scanner_name_.substr(0, pos)).c_str()); - } -} -void scanner::update_config(void) -{ - if (!cfg_) - return; - - gb::sane_config_schm* schm = cfg_->get_scheme(); - std::string notice(""); - - if (schm) - { - //schm->update(&scanner::is_option_float, handle_, &callback::option_title_2_name, ¬ice); - //if (notice.length()) - //{ - // std::wstring msg(local_trans::lang_trans_between_hz936(L"\u4E0B\u5217\u914D\u7F6E\u6570\u636E\u9519\u8BEF\uFF0C\u5DF2\u7ECF\u6062\u590D\u5230\u9ED8\u8BA4\u503C\u3002\u5982\u679C\u9700\u8981\uFF0C\u8BF7\u91CD\u65B0\u8BBE\u7F6E") + L"\r\n\r\n"); - // size_t pos = notice.find("\r\n"); - // - // while (pos != std::string::npos) - // { - // msg += local_trans::a2u(callback::option_name_2_title(notice.substr(0, pos).c_str()), CP_UTF8) + L"\r\n"; - // notice.erase(0, pos + 2); - // pos = notice.find("\r\n"); - // } - // if (!IsWindow(app_wnd_)) - // callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(L"\u52A0\u8F7D\u914D\u7F6E").c_str()); - // MessageBoxW(app_wnd_, msg.c_str(), local_trans::lang_trans_between_hz936(L"\u52A0\u8F7D\u914D\u7F6E").c_str(), MB_OK | MB_ICONINFORMATION); - //} - schm->release(); - } -} -void scanner::load_config(const wchar_t* file) -{ - if (cfg_) - { - cfg_->load_file(local_trans::u2a(file).c_str()); - update_config(); - } -} -void scanner::save_config(const wchar_t* file) -{ - if(cfg_) - cfg_->save(local_trans::u2a(file).c_str()); -} -void scanner::apply_config(void) -{ - if (callback::apply_current_config) - callback::apply_current_config(local_trans::u2a(scanner_name_.c_str(), CP_UTF8).c_str(), handle_, &sane_api_); - else if (cfg_) - { - gb::sane_config_schm* schm = cfg_->get_scheme(); - - if (!schm) - return; - - apply_scheme(schm); - schm->release(); - } -} -void scanner::on_ui_event(int uev, void* sender) -{ - bool indicator = sender == indicator_.get(); - if (uev == SANE_EVENT_SCAN_FINISHED || uev == SANE_EVENT_UI_CLOSE_NORMAL || uev == SANE_EVENT_UI_CLOSE_CANCEL) - { - if (uev == SANE_EVENT_UI_CLOSE_CANCEL) - user_cancel_ = true; - - if (indicator) - indicator_.reset(); - - is_scanning_ = false; - if (err_ && setting_.get()) - { - return; - } - } - - //int(__stdcall * h)(int, void*) = scanner_ev_handler_; - //if (h) - //{ - // if (SANE_EVENT_UI_CLOSE_SETTING == uev) - // { - // is_scanning_ = false; - // setting_.reset(); - // } - - // h(uev, evh_param_); - // return; - //} - - //if (prev_start_result_ != SANE_STATUS_GOOD && indicator) - // indicator_.reset(); - //else - { - //if (uev == SANE_EVENT_UI_SCAN_COMMAND) - //{ - // ui_show_progress(NULL); - // start(); - // return; - //} - - if (/*events_.count() > 5 && !is_ui_wait_img_ &&*/ - (uev == SANE_EVENT_UI_CLOSE_CANCEL || uev == SANE_EVENT_UI_CLOSE_NORMAL || uev == SANE_EVENT_UI_CLOSE_SETTING)) - { - // events_.clear(); - ui_hide(); - if(indicator || !indicator_.get()) - uev = SANE_EVENT_SCAN_FINISHED; - else - uev = SANE_EVENT_UI_CLOSE_SETTING; - } - - events_.save(uev, sizeof(uev)); - ev_cnt_++; - } - - if (ev_cnt_ == events_.count() && - (ev_cnt_ >= 5 || (ev_cnt_ > 1 && !is_scanning_))) - { - // maybe no event has been handled by APP, triggered by callback - int(__stdcall * h)(int, void*) = scanner_ev_handler_; - if (h) - { - wchar_t info[128] = { 0 }; - swprintf_s(info, _countof(info) - 1, L"[CRAZY]%d scanner events stored but APP has no action, we try to trigger it ONCE ...\r\n", ev_cnt_); - ev_cnt_--; - h(events_.take(), evh_param_); - } - } -} -std::string scanner::choose_scanner(const std::vector& scanners) -{ - if (scanners.empty()) - return ""; - - std::vector devs; - std::string sel(""); - int id = 1; - - for (size_t i = 0; i < scanners.size(); ++i) - { - SANE_Handle h = NULL; - int ret = hg_sane_middleware::instance()->open_device(scanners[i].c_str(), &h); - - if (h) - { - std::string sn(""); - scanner::control_read_string(h, IO_CTRL_CODE_GET_SERIAL, sn); - if (sn.length()) - { - DEVQUE dev; - dev.id = id++; - dev.name = scanners[i]; - dev.sn = sn; - devs.push_back(dev); - } - hg_sane_middleware::instance()->close_device(h); - } - } - - if (devs.size() == 0) - sel = scanners[0]; - else if (devs.size() == 1) - sel = devs[0].name; - else if (callback::choose_scanner) - { - id = callback::choose_scanner(devs); - if (id != -1) - { - for (auto& v : devs) - { - if (v.id == id) - { - sel = v.name; - break; - } - } - } - } - else - { - dlg_choose_dev dlg(NULL, devs); - dlg.show(true, true); - sel = dlg.get_selected_device(); - } - - return sel; -} -int scanner::open(void) -{ - int ret = close(); - std::vector que; - std::string name(""); - - scanner::get_scanner_name(id_, que); - - scanner_name_ = L""; - if (que.empty()) - return SCANNER_ERR_DEVICE_NOT_FOUND; - - if (que.size() == 1) - name = que[0]; - else - { - name = choose_scanner(que); - if (name.empty()) - return SCANNER_ERR_USER_CANCELED; - } - - ret = hg_sane_middleware::instance()->open_device(name.c_str(), &handle_); - if (ret == SANE_STATUS_GOOD) - { - size_t pid = -1; - - transport_config_file(); - callback::reg_callback(handle_, this); - scanner_name_ = local_trans::a2u(name.c_str(), CP_UTF8); - pid = scanner_name_.find(L" - "); - if (pid == -1) - pid = scanner_name_.length(); - ret = init_options_id(); - load_config((cfg_path_ + scanner_name_.substr(0, pid) + L".cfg").c_str()); - apply_config(); - } - else - { - std::wstring msg(local_trans::a2u(hg_scanner_err_description(ret), CP_UTF8)); - HWND parent = callback::find_main_wnd(); - - if (!IsWindow(parent)) - callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_OPEN_FAILED).c_str()); - MessageBoxW(parent, msg.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_OPEN_FAILED).c_str(), MB_OK | MB_ICONERROR); - } - - return ret; -} -int scanner::close(void) -{ - scanner_ev_handler_ = NULL; - ui_hide(); - callback::unreg_callback(this); - if (handle_) - { - hg_sane_middleware::instance()->close_device(handle_); - } - handle_ = NULL; - ex_id_ = EXTENSION_ID_BASE; - - return SCANNER_ERR_OK; -} -int scanner::init_options_id(void) -{ - SANE_Int op_id = 1; - const SANE_Option_Descriptor* desc = NULL; - int ret = SCANNER_ERR_OK; - -#define SET_OPT_ID(var, predef, func) \ - SET_SANE_OPT_ID(op_id, var, predef, desc->name, func) - - while ((desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (const void*)op_id))) - { - void* val = hg_sane_middleware::instance()->get_def_value(handle_, (void*)op_id, NULL, true); - if (val) - { - size_t len = 0; - switch (desc->type) - { - case SANE_TYPE_BOOL: - len = sizeof(SANE_Bool); - break; - case SANE_TYPE_INT: - len = sizeof(SANE_Int); - break; - case SANE_TYPE_FIXED: - len = sizeof(SANE_Fixed); - break; - case SANE_TYPE_STRING: - len = lstrlenA((char*)val); - break; - default: - break; - } - if (len && cfg_) - { - if (desc->type == SANE_TYPE_STRING) - { - std::string deflan(to_default_language((char*)val, nullptr)); - cfg_->set_default_value(op_id, desc->name, desc->title, &deflan[0], deflan.length(), desc->type); - } - else - cfg_->set_default_value(op_id, desc->name, desc->title, (char*)val, len, desc->type); - } - local_utility::free_memory(val); - } - - SET_OPT_ID(is_multiout, IS_MULTI_OUT, extension_none) - else SET_OPT_ID(multiout_type, MULTI_OUT_TYPE, extension_multiout_type) - else SET_OPT_ID(color_mode, COLOR_MODE, extension_color_mode) - else SET_OPT_ID(erase_color, FILTER, extension_erase_color) - else SET_OPT_ID(erase_multiout_red, RID_MULTIOUT_RED, extension_none) - else SET_OPT_ID(erase_paper_red, RID_ANSWER_SHEET_RED, extension_none) - else SET_OPT_ID(is_erase_background, ERASE_BACKGROUND, extension_none) - else SET_OPT_ID(background_color_range, BKG_COLOR_RANGE, extension_none) - else SET_OPT_ID(sharpen, SHARPEN, extension_sharpen) - else SET_OPT_ID(erase_morr, RID_MORR, extension_none) - else SET_OPT_ID(erase_grids, RID_GRID, extension_none) - else SET_OPT_ID(error_extend, ERROR_EXTENSION, extension_none) - else SET_OPT_ID(is_noise_modify, NOISE_OPTIMIZE, extension_none) - else SET_OPT_ID(noise_threshold, NOISE_SIZE, extension_none) - else SET_OPT_ID(paper, PAPER, extension_paper) - else SET_OPT_ID(is_custom_area, CUSTOM_AREA, extension_none) - else SET_OPT_ID(curstom_area_l, CUSTOM_AREA_LEFT, extension_none) - else SET_OPT_ID(curstom_area_r, CUSTOM_AREA_RIGHT, extension_none) - else SET_OPT_ID(curstom_area_t, CUSTOM_AREA_TOP, extension_none) - else SET_OPT_ID(curstom_area_b, CUSTOM_AREA_BOTTOM, extension_none) - else SET_OPT_ID(is_size_check, SIZE_CHECK, extension_none) - else SET_OPT_ID(page, PAGE, extension_page) - else SET_OPT_ID(blank_page_threshold, DISCARD_BLANK_SENS, extension_none) - else SET_OPT_ID(resolution, RESOLUTION, extension_none) - else SET_OPT_ID(image_quality, IMAGE_QUALITY, extension_none) - else SET_OPT_ID(is_swap, EXCHANGE, extension_none) - else SET_OPT_ID(is_split, SPLIT, extension_none) - else SET_OPT_ID(is_auto_deskew, ANTI_SKEW, extension_none) - else SET_OPT_ID(is_custom_gamma, IS_CUSTOM_GAMMA, extension_none) - else SET_OPT_ID(bright, BRIGHTNESS, extension_none) - else SET_OPT_ID(contrast, CONTRAST, extension_none) - else SET_OPT_ID(gamma, GAMMA, extension_none) - else SET_OPT_ID(is_erase_black_frame, ERASE_BLACK_FRAME, extension_none) - else SET_OPT_ID(deep_sample, DARK_SAMPLE, extension_none) - else SET_OPT_ID(threshold, THRESHOLD, extension_none) - else SET_OPT_ID(anti_noise, ANTI_NOISE_LEVEL, extension_none) - else SET_OPT_ID(margin, MARGIN, extension_none) - else SET_OPT_ID(fill_background, FILL_BKG_MODE, extension_fill_bkg_method) - else SET_OPT_ID(is_anti_permeate, IS_ANTI_PERMEATE, extension_none) - else SET_OPT_ID(anti_permeate_level, ANTI_PERMEATE_LEVEL, extension_none) - else SET_OPT_ID(is_erase_hole, RID_HOLE, extension_none) - else SET_OPT_ID(search_hole_range, SEARCH_HOLE_RANGE, extension_none) - else SET_OPT_ID(is_filling_color, IS_FILL_COLOR, extension_none) - else SET_OPT_ID(is_ultrasonic_check, IS_ULTROSONIC_CHECK, extension_none) - else SET_OPT_ID(is_check_staple, IS_CHECK_STAPLE, extension_none) - else SET_OPT_ID(scan_mode, SCAN_MODE, extension_none) - else SET_OPT_ID(scan_count, SCAN_COUNT, extension_none) - else SET_OPT_ID(text_direction, TEXT_DIRECTION, extension_text_direction) - else SET_OPT_ID(is_rotate_bkg180, IS_ROTATE_BKG_180, extension_none) - else SET_OPT_ID(is_check_dogear, IS_CHECK_DOG_EAR, extension_none) - else SET_OPT_ID(dogear_size, DOG_EAR_SIZE, extension_none) - else SET_OPT_ID(is_check_skew, IS_CHECK_ASKEW, extension_none) - else SET_OPT_ID(skew_range, ASKEW_RANGE, extension_none) - else SET_OPT_ID(black_white_threshold, BINARY_THRESHOLD, extension_none) - else SET_OPT_ID(is_photo_mode, IS_PHOTO_MODE, extension_none) - else SET_OPT_ID(double_feed_handle, DOUBLE_FEED_HANDLE, extension_none) - else SET_OPT_ID(scan_when_paper_on, WAIT_TO_SCAN, extension_none) - else SET_OPT_ID(feed_strength, FEED_STRENGTH, extension_none) - else SET_OPT_ID(power_scheme, TIME_TO_SLEEP, extension_none) - else SET_OPT_ID(is_auto_strength, IS_AUTO_FEED_STRENGTH, extension_none) - else SET_OPT_ID(feed_strength_value , FEED_STRENGTH_VALUE, extension_none) - else SET_OPT_ID(is_reverse_bw, REVERSE_01, extension_none) - else SET_OPT_ID(is_erase_hole_l, RID_HOLE_L, extension_none) - else SET_OPT_ID(search_hole_range_l, SEARCH_HOLE_RANGE_L, extension_none) - else SET_OPT_ID(is_erase_hole_r, RID_HOLE_R, extension_none) - else SET_OPT_ID(search_hole_range_r, SEARCH_HOLE_RANGE_R, extension_none) - else SET_OPT_ID(is_erase_hole_t, RID_HOLE_T, extension_none) - else SET_OPT_ID(search_hole_range_t, SEARCH_HOLE_RANGE_T, extension_none) - else SET_OPT_ID(is_erase_hole_b, RID_HOLE_B, extension_none) - else SET_OPT_ID(search_hole_range_b, SEARCH_HOLE_RANGE_B, extension_none) - else SET_OPT_ID(fold_direction, FOLD_TYPE, extension_none) - else SET_OPT_ID(fold_type, FOLD_TYPE, extension_none) - else SET_OPT_ID(color_correction, COLOR_CORRECTION, extension_none) - op_id++; - } - -#define EX_APPENDIX_API(name) \ - { \ - EXAPI ea; \ - ea.ind = ex_##name##_id_ = ex_id_++; \ - ea.ex_api = &scanner::handle_ex_##name; \ - ea.base_ind = -1; \ - ex_opts_.push_back(ea); \ - } - EX_APPENDIX_API(final_compression); - EX_APPENDIX_API(final_format); - EX_APPENDIX_API(serial); - EX_APPENDIX_API(to_be_scan); - EX_APPENDIX_API(scan_with_hole); - EX_APPENDIX_API(device_code); - EX_APPENDIX_API(power); - EX_APPENDIX_API(hardware_version); - EX_APPENDIX_API(ip); - - if (black_white_threshold_id_ == -1) - black_white_threshold_id_ = 0x8836; - - if (is_erase_hole_id_ == -1) - { - // 兼容老的除孔算法 - EXAPI ea; - - ea.ind = is_erase_hole_id_ = ex_id_++; - ea.base_ind = is_erase_hole_l_id_; - ea.ex_api = &scanner::handle_ex_erase_hole; - ex_opts_.push_back(ea); - - ea.ind = search_hole_range_id_ = ex_id_++; - ea.base_ind = search_hole_range_l_id_; - ea.ex_api = &scanner::handle_ex_search_hole_range; - ex_opts_.push_back(ea); - } - - return ret; -} -int scanner::control_read_string(int code, std::string& ret) -{ - return scanner::control_read_string(handle_, code, ret); -} - -void scanner::extension_none(int id) -{ -} -void scanner::extension_multiout_type(int id) -{ - EXAPI ea; - - ex_multiout_type_id_ = ex_id_++; - ea.ind = ex_multiout_type_id_; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_multiout; - - ex_opts_.push_back(ea); -} -void scanner::extension_color_mode(int id) -{ - EXAPI ea; - - ea.ind = ex_color_mode_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_color_mode; - ex_opts_.push_back(ea); - - ex_auto_color_type_id_ = ex_id_++; - ea.base_ind = id; - ea.ind = ex_auto_color_type_id_; - ea.ex_api = &scanner::handle_ex_auto_color_type; - ex_opts_.push_back(ea); -} -void scanner::extension_sharpen(int id) -{ - EXAPI ea; - - ex_sharpen_id_ = ex_id_++; - ea.base_ind = id; - ea.ind = ex_sharpen_id_; - ea.ex_api = &scanner::handle_ex_sharpen; - - ex_opts_.push_back(ea); -} -void scanner::extension_paper(int id) -{ - EXAPI ea; - - ea.ind = ex_paper_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_paper; - ex_opts_.push_back(ea); - - ea.ind = ex_paper_lateral_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_paper_lateral; - ex_opts_.push_back(ea); - - ea.ind = ex_auto_paper_size_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_auto_paper_size; - ex_opts_.push_back(ea); - - ea.ind = ex_is_paper_auto_crop_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_auto_paper_crop; - ex_opts_.push_back(ea); -} -void scanner::extension_fill_bkg_method(int id) -{ - EXAPI ea; - - ea.ind = ex_fill_background_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_fill_background; - ex_opts_.push_back(ea); -} -void scanner::extension_text_direction(int id) -{ - EXAPI ea; - - ea.ind = ex_text_direction_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_text_direction; - ex_opts_.push_back(ea); -} -void scanner::extension_page(int id) -{ - EXAPI ea; - wchar_t msg[128] = { 0 }; - - ea.ind = ex_duplex_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_duplex; - ex_opts_.push_back(ea); - { - swprintf_s(msg, _countof(msg) - 1, L"handle_ex_duplex of id: %d\r\n", ea.ind); - log_info(msg, 0); - } - - ea.ind = ex_discard_blank_page_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_discard_blank_page; - ex_opts_.push_back(ea); - { - swprintf_s(msg, _countof(msg) - 1, L"handle_ex_discard_blank_page of id: %d\r\n", ea.ind); - log_info(msg, 0); - } - - ea.ind = ex_discard_blank_receipt_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_discard_blank_receipt; - ex_opts_.push_back(ea); - { - swprintf_s(msg, _countof(msg) - 1, L"handle_ex_discard_blank_receipt of id: %d\r\n", ea.ind); - log_info(msg, 0); - } - - ea.ind = ex_is_page_fold_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_page_fold; - ex_opts_.push_back(ea); - { - swprintf_s(msg, _countof(msg) - 1, L"handle_ex_page_fold of id: %d\r\n", ea.ind); - log_info(msg, 0); - } -} -void scanner::extension_erase_color(int id) -{ - EXAPI ea; - - ea.ind = ex_color_filter_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_color_filter; - ex_opts_.push_back(ea); - - ea.ind = ex_color_enhance_id_ = ex_id_++; - ea.base_ind = id; - ea.ex_api = &scanner::handle_ex_color_enhance; - ex_opts_.push_back(ea); -} -bool scanner::get_option_value_with_parent(int sn, set_opt_value setv, void* param) // return true if handled -{ - bool handled = true; - - if (sn == scan_count_id_) - { - SANE_Option_Descriptor* parent = hg_sane_middleware::instance()->get_option_descriptor(handle_, (const void*)scan_mode_id_); - char* buf = new char[parent->size + 4]; - - memset(buf, 0, parent->size); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)scan_mode_id_, buf); - handled = compare_sane_opt(local_trans::lang_trans_between_hz936(OPTION_VALUE_SMZS_LXSM, true, nullptr), buf); - delete[] buf; - if (handled) - { - int count = -1; - value_role role = VAL_ROLE_CURRENT; - buf = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)scan_mode_id_); - if (compare_sane_opt(local_trans::lang_trans_between_hz936(OPTION_VALUE_SMZS_LXSM, true, nullptr), buf)) - role = value_role(role | VAL_ROLE_DEFAULT); - local_utility::free_memory(buf); - - setv(&count, value_role(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), VAL_LIMIT_NONE, param); - } - } - else - handled = false; - - return handled; -} -bool scanner::set_option_value_with_parent(int sn, void* data, int* err) // return true if handled sn -{ - bool handled = false; - - if (sn == scan_count_id_) - { - SANE_Option_Descriptor* parent = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)scan_mode_id_); - char* val = new char[parent->size + 4]; - SANE_Int after = 0; - - memset(val, 0, parent->size + 4); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)scan_mode_id_, val); - if (compare_sane_opt(local_trans::lang_trans_between_hz936(OPTION_VALUE_SMZS_LXSM, true, nullptr), val)) - { - if (*(int*)data != -1) - { - strcpy(val, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMZS_SMZDZS, true, nullptr)); - *err = hg_sane_middleware::instance()->set_option(handle_, (void*)scan_mode_id_, SANE_ACTION_SET_VALUE, val, &after); - } - } - else if (*(int*)data == -1) - { - strcpy(val, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMZS_LXSM, true, nullptr)); - *err = hg_sane_middleware::instance()->set_option(handle_, (void*)scan_mode_id_, SANE_ACTION_SET_VALUE, val, &after); - } - delete[] val; - } - - return handled; -} -int scanner::set_option_value(int sn, SANE_Value_Type type, int size, void* data) -{ - char* buf = NULL; - SANE_Bool sb = SANE_FALSE; - SANE_Int si = 0, after = 0; - SANE_Fixed sf = 0; - int ret = SCANNER_ERR_OK; - void* val = data; - - if (type == SANE_TYPE_BOOL) - { - sb = *(bool*)data ? SANE_TRUE : SANE_FALSE; - val = &sb; - } - else if (type == SANE_TYPE_INT) - { - si = *(int*)data; - val = &si; - } - else if (type == SANE_TYPE_FIXED) - { - sf = SANE_FIX(*(float*)data); - val = &sf; - } - else - { - buf = new char[size + 4]; - memset(buf, 0, size + 4); - strcpy(buf, ((std::string*)data)->c_str()); - val = buf; - } - - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)sn, SANE_ACTION_SET_VALUE, val, &after); - - if (type == SANE_TYPE_BOOL) - { - *(bool*)data = sb == SANE_TRUE; - } - else if (type == SANE_TYPE_INT) - { - *(int*)data = si; - } - else if (type == SANE_TYPE_FIXED) - { - *(float*)data = (float)SANE_UNFIX(sf); - } - else if(buf) - { - strcpy((char*)val, buf); - delete[] buf; - } - - return ret; -} -int scanner::set_is_multiout(bool enable) -{ - int ret = SCANNER_ERR_OK; - - if (is_multiout_id_ > 0) - { - SANE_Bool multi = SANE_FALSE; - SANE_Int after = 0; - - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)is_multiout_id_, &multi); // parent item ... - if (enable ^ (multi == SANE_TRUE)) - { - multi = enable ? SANE_TRUE : SANE_FALSE; - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)is_multiout_id_, SANE_ACTION_SET_VALUE, &multi, &after); - after = 0; - } - } - - return ret; -} - -scanner::EXAPIPOS scanner::find_ex_api(int op_id) -{ - return std::find(ex_opts_.begin(), ex_opts_.end(), op_id); -} -void scanner::apply_scheme(gb::sane_config_schm* schm) -{ - // restore ... - hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_RESTORE_SETTINGS, nullptr, nullptr); - - if (!schm) - return; - - std::string n(""), v(""), ver(schm->get_version()); - - if (schm->first_config(n, v)) - { - do - { - int id = schm->id_from_name(n.c_str()); - if (id == -1) - { - if (gb::sane_config_schm::is_option_data(n)) - { - id = schm->id_from_name(n.c_str()); - if (id == is_custom_gamma_id_) - { - if (v.length() == sizeof(SANE_Gamma)) - { - unsigned int l = v.length(); - hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_SET_CUSTOM_GAMMA, &v[0], &l); - } - else - { - wchar_t info[128] = { 0 }; - swprintf_s(info, _countof(info) - 1, L"ERROR: custom gamma data length is %u, but we expect %u.\r\n", v.length(), sizeof(SANE_Gamma)); - log_info(info, 0); - } - } - } - } - else - { - v = from_default_language(v.c_str(), nullptr); - void* data = &v[0]; - SANE_Fixed fixed = 0; - const SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (const void*)id); - if (desc) - { - char* buf = NULL; - SANE_Int after = 0; - - if (desc->type == SANE_TYPE_STRING) - { - buf = new char[desc->size + 4]; - memset(buf, 0, desc->size + 4); - strcpy(buf, v.c_str()); - data = buf; - } - hg_sane_middleware::instance()->set_option(handle_, (const void*)id, SANE_ACTION_SET_VALUE, data, &after); - - if (buf) - delete[] buf; - } - } - } while (schm->next_config(n, v)); - } -} - -EX_OPTION_HANDLER_IMPL(multiout) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - SANE_Bool parent = SANE_FALSE; - - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)is_multiout_id_, &parent); - if (setv) - { - char* cur = (char*)hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id), - * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - int now = sane_opt_trans::multiout_value_to_twain(cur), - init = sane_opt_trans::multiout_value_to_twain(def), - val = 0; - - local_utility::free_memory(def); - local_utility::free_memory(cur); - - { - // parent item ... - if (!parent) - now = MULTI_OUT_NONE; - } - - do - { - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - // we have no 'MULTI_OUT_NONE' item in this option, this is used as is_multiout_id_ - val = MULTI_OUT_NONE; - value_role role = val == now ? VAL_ROLE_CURRENT : VAL_ROLE_NONE; - if (val == init) - role = (value_role)(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, VAL_LIMIT_ENUM, data)) - break; - for (int i = 0; desc->constraint.string_list[i]; ++i) - { - value_role role = VAL_ROLE_NONE; - val = sane_opt_trans::multiout_value_to_twain(desc->constraint.string_list[i]); - if (val == now) - role = VAL_ROLE_CURRENT; - if (val == init) - role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, VAL_LIMIT_ENUM, data)) - break; - } - } - else - set_cur_and_def_value(now, init, setv, data); - } while (0); - } - else - { - char* val = new char[desc->size]; - const char* in = sane_opt_trans::multiout_value_from_twain(*(int*)data); - SANE_Int after = 0; - - if (in && strcmp(in, "\346\227\240")) - { - ret = set_is_multiout(true); - if (ret == SANE_STATUS_GOOD) - { - strcpy(val, in); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, val, &after); - } - } - else - { - // disable multi-out, let multiout type aside - ret = set_is_multiout(false); - } - delete[] val; - ret = local_utility::sane_statu_2_scanner_err(ret); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(auto_color_type) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - int len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - if (setv) - { - char* def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - int init = sane_opt_trans::auto_color_type_to_twain(def); - - local_utility::free_memory(def); - len = sane_opt_trans::auto_color_type_to_twain(buf); - set_cur_and_def_value(len, init, setv, data); - } - else - { - SANE_Int after = 0; - - // ret = set_is_multiout(false); - if (ret == SCANNER_ERR_OK) - { - strcpy(buf, sane_opt_trans::auto_color_type_from_twain(*(int*)data)); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - } - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(color_mode) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - - if (setv) - { - char* cur = (char*)hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id), - * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - int now = sane_opt_trans::color_mode_to_twain(cur), // sane_opt_trans::multiout_value_to_twain(cur) - init = sane_opt_trans::color_mode_to_twain(def), - val = 0; - - local_utility::free_memory(def); - local_utility::free_memory(cur); - - do - { - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - for (int i = 0; desc->constraint.string_list[i]; ++i) - { - value_role role = VAL_ROLE_NONE; - val = sane_opt_trans::color_mode_to_twain(desc->constraint.string_list[i]); - if (val == now) - role = VAL_ROLE_CURRENT; - if (val == init) - role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, VAL_LIMIT_ENUM, data)) - break; - } - } - else - set_cur_and_def_value(now, init, setv, data); - } while (0); - } - else - { - SANE_Int after = 0; - - // ret = set_is_multiout(false); - if (ret == SCANNER_ERR_OK) - { - char* val = new char[desc->size]; - const char* in = sane_opt_trans::color_mode_from_twain(*(int*)data); - - strcpy(val, in); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, val, &after); - delete[] val; - } - ret = local_utility::sane_statu_2_scanner_err(ret); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(sharpen) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - - if (setv) - { - char* cur = (char*)hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id), - * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - int now = sane_opt_trans::multiout_value_to_twain(cur), - init = sane_opt_trans::sharpen_to_twain(def), - val = 0; - - local_utility::free_memory(def); - local_utility::free_memory(cur); - - do - { - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - for (int i = 0; desc->constraint.string_list[i]; ++i) - { - value_role role = VAL_ROLE_NONE; - val = sane_opt_trans::sharpen_to_twain(desc->constraint.string_list[i]); - if (val == now) - role = VAL_ROLE_CURRENT; - if (val == init) - role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, VAL_LIMIT_ENUM, data)) - break; - } - } - else - set_cur_and_def_value(now, init, setv, data); - } while (0); - } - else - { - char* val = new char[desc->size]; - const char* in = sane_opt_trans::sharpen_from_twain(*(int*)data); - SANE_Int after = 0; - - strcpy(val, in); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, val, &after); - delete[] val; - ret = local_utility::sane_statu_2_scanner_err(ret); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(paper) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - int len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - if (setv) - { - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - char* def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - int now = sane_opt_trans::paper_to_twain(buf), - init = sane_opt_trans::paper_to_twain(def), - val = 0; - - local_utility::free_memory(def); - do - { - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - for (int i = 0; desc->constraint.string_list[i]; ++i) - { - value_role role = VAL_ROLE_NONE; - val = sane_opt_trans::paper_to_twain(desc->constraint.string_list[i]); - if (val == -1) - continue; - if (val == now) - role = VAL_ROLE_CURRENT; - if (val == init) - role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, VAL_LIMIT_ENUM, data)) - break; - } - } - else - set_cur_and_def_value(now, init, setv, data); - } while (0); - } - else if (sane_opt_trans::paper_from_twain(*(int*)data)) - { - SANE_Int after = 0; - strcpy(buf, sane_opt_trans::paper_from_twain(*(int*)data)); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - } - else - ret = SCANNER_ERR_INVALID_PARAMETER; - - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(paper_lateral) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - int len = desc->size + 4; - char* buf = new char[len]; - const char* lateral_swap = NULL; - bool lateral = false; - - memset(buf, 0, len); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - lateral_swap = sane_opt_trans::switch_paper_lateral(buf); - lateral = sane_opt_trans::is_paper_lateral(buf); - if (setv) - { - set_cur_and_def_value(lateral, false, setv, data); - } - else if (lateral_swap) - { - SANE_Int after = 0; - if (lateral != *(bool*)data) - { - strcpy(buf, lateral_swap); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - } - else - { - SANE_Int after = 0; - if (*(bool*)data) - { - // set to A4Lateral ... - strcpy(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_ZZCC_A4HX, true, nullptr)); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - //ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - } - - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(auto_paper_size) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - int len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - if (setv) - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - bool yes = strcmp(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_ZZCC_PPYSCC, true, nullptr)) == 0, - def = strcmp(init, local_trans::lang_trans_between_hz936(OPTION_VALUE_ZZCC_PPYSCC, true, nullptr)) == 0; - - local_utility::free_memory(init); - set_cur_and_def_value(yes, def, setv, data); - } - else - { - SANE_Int after = 0; - strcpy(buf, *(bool*)data ? local_trans::lang_trans_between_hz936(OPTION_VALUE_ZZCC_PPYSCC, true, nullptr) : local_trans::lang_trans_between_hz936(OPTION_VALUE_ZZCC_A4, true, nullptr)); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(auto_paper_crop) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - int len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - if (setv) - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - bool yes = strcmp(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_ZZCC_ZDSMCCZDCQ, true, nullptr)) == 0, - def = strcmp(init, OPTION_VALUE_ZZCC_ZDSMCCZDCQ) == 0; - - local_utility::free_memory(init); - set_cur_and_def_value(yes, def, setv, data); - } - else - { - SANE_Int after = 0; - strcpy(buf, *(bool*)data ? local_trans::lang_trans_between_hz936(OPTION_VALUE_ZZCC_ZDSMCCZDCQ, true, nullptr) : local_trans::lang_trans_between_hz936(OPTION_VALUE_ZZCC_ZDSMCC, true, nullptr)); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(text_direction) -{ - int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - int len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - if (setv) - { - char* def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - float now = .0f, init = sane_opt_trans::text_direction_to_twain(def), val = .0f; - - local_utility::free_memory(def); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - now = sane_opt_trans::text_direction_to_twain(buf); - do - { - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - for (int i = 0; desc->constraint.string_list[i]; ++i) - { - value_role role = VAL_ROLE_NONE; - val = sane_opt_trans::text_direction_to_twain(desc->constraint.string_list[i]); - if (IS_DOUBLE_EQUAL(val, now)) - role = VAL_ROLE_CURRENT; - if (IS_DOUBLE_EQUAL(val, init)) - role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, VAL_LIMIT_ENUM, data)) - break; - } - } - else - set_cur_and_def_value(now, init, setv, data); - } while (0); - } - else - { - SANE_Int after = 0; - - strcpy(buf, sane_opt_trans::text_direction_from_twain(*(float*)data)); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(duplex) -{ - int ret = SCANNER_ERR_OK; - bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - unsigned len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - if (setv) - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - set_cur_and_def_value(strcmp(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_SM, true, nullptr)) == 0, strcmp(init, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_SM, true, nullptr)) == 0, setv, data); - local_utility::free_memory(init); - } - else - { - strcpy(buf, val ? local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_SM, true, nullptr) : local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_DM, true, nullptr)); - SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(fill_background) -{ - int ret = SCANNER_ERR_OK; - bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - unsigned len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - if (setv) - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - val = strcmp(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_SM, true, nullptr)) == 0; - set_cur_and_def_value(strcmp(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_BJTCFS_TDBX, true, nullptr)) == 0, strcmp(init, local_trans::lang_trans_between_hz936(OPTION_VALUE_BJTCFS_TDBX, true, nullptr)) == 0, setv, data); - local_utility::free_memory(init); - } - else - { - strcpy(buf, val ? local_trans::lang_trans_between_hz936(OPTION_VALUE_BJTCFS_TDBX, true, nullptr) : local_trans::lang_trans_between_hz936(OPTION_VALUE_BJTCFS_ADBX, true, nullptr)); - SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(discard_blank_page) -{ - int ret = SCANNER_ERR_OK; - bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - unsigned len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - if (setv) - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - bool def = strcmp(init, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_TGKBYTY, true, nullptr)) == 0; - - local_utility::free_memory(init); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - val = strcmp(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_TGKBYTY, true, nullptr)) == 0; - set_cur_and_def_value(val, def, setv, data); - } - else - { - if (val) - strcpy(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_TGKBYTY, true, nullptr)); - else - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - strcpy(buf, init); - local_utility::free_memory(init); - } - SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(discard_blank_receipt) -{ - int ret = SCANNER_ERR_OK; - bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - unsigned len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - if (setv) - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - bool def = strcmp(init, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_TGKBYFPZ, true, nullptr)) == 0; - - local_utility::free_memory(init); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - val = strcmp(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_TGKBYFPZ, true, nullptr)) == 0; - set_cur_and_def_value(val, def, setv, data); - } - else - { - if (val) - strcpy(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_TGKBYFPZ, true, nullptr)); - else - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - strcpy(buf, init); - local_utility::free_memory(init); - } - SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(page_fold) -{ - int ret = SCANNER_ERR_OK; - bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - unsigned len = desc->size + 4; - char* buf = new char[len]; - - memset(buf, 0, len); - if (setv) - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - bool def = strcmp(init, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_DZ, true, nullptr)) == 0; - - local_utility::free_memory(init); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - val = strcmp(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_DZ, true, nullptr)) == 0; - set_cur_and_def_value(val, def, setv, data); - } - else - { - if (val) - strcpy(buf, local_trans::lang_trans_between_hz936(OPTION_VALUE_SMYM_DZ, true, nullptr)); - else - { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); - strcpy(buf, init); - local_utility::free_memory(init); - } - SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - - return ret; -} -EX_OPTION_HANDLER_IMPL(color_filter) // int (filter_value) -{ - int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - char* buf = NULL; - unsigned int len = 0; - - if (desc) - { - len = desc->size + 4; - buf = new char[len]; - memset(buf, 0, len); - if (setv) - { - bool filter = false; - int val = FILTER_NONE, now = FILTER_NONE; - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - now = sane_opt_trans::filter_enhance_value_to_twain(buf, &filter); - if (!filter) - now = val; - do - { - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - for (int i = 0; desc->constraint.string_list[i]; ++i) - { - value_role role = VAL_ROLE_NONE; - int v = sane_opt_trans::filter_enhance_value_to_twain(desc->constraint.string_list[i], &filter); - if (!filter && v != FILTER_NONE) - continue; - if (v == now) - role = VAL_ROLE_CURRENT; - if (v == val) - role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&v, role, VAL_LIMIT_ENUM, data)) - break; - } - } - }while (0); - } - else - { - const char* val = sane_opt_trans::filter_enhance_value_from_twain(*((int*)data), true); - SANE_Int after = 0; - - strcpy(buf, val); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(color_enhance) // int (enhance_value) -{ - int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - char* buf = NULL; - unsigned int len = 0; - - if (desc) - { - len = desc->size + 4; - buf = new char[len]; - memset(buf, 0, len); - if (setv) - { - bool filter = false; - int val = ENHANCE_NONE, now = ENHANCE_NONE; - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); - now = sane_opt_trans::filter_enhance_value_to_twain(buf, &filter); - if (filter) - now = val; - do - { - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - for (int i = 0; desc->constraint.string_list[i]; ++i) - { - value_role role = VAL_ROLE_NONE; - int v = sane_opt_trans::filter_enhance_value_to_twain(desc->constraint.string_list[i], &filter); - if (filter && v != ENHANCE_NONE) - continue; - if (v == now) - role = VAL_ROLE_CURRENT; - if (v == val) - role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&v, role, VAL_LIMIT_ENUM, data)) - break; - } - } - } while (0); - } - else - { - const char* val = sane_opt_trans::filter_enhance_value_from_twain(*((int*)data), false); - SANE_Int after = 0; - - strcpy(buf, val); - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - delete[] buf; - } - - return ret; -} - -EX_OPTION_HANDLER_IMPL(final_compression) -{ - int ret = SCANNER_ERR_OK; - int* compression = (int*)data; - unsigned int len = sizeof(*compression); - - if (setv) - { - int val = 0; - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_FINAL_COMPRESSION, &val, &len); - if (ret == SANE_STATUS_GOOD) - { - int i = SANE_COMPRESSION_FIRST; - for (; i < SANE_COMPRESSION_LAST; ++i) - { - value_role role = VAL_ROLE_NONE; - if (i == val) - role = VAL_ROLE_CURRENT; - if (i == SANE_COMPRESSION_NONE) - role = value_role(role | VAL_ROLE_DEFAULT); - int v = sane_opt_trans::compression_to_twain(i); - if (!setv(&v, role, VAL_LIMIT_ENUM, data)) - break; - } - } - } - else - { - int val = sane_opt_trans::compression_from_twain(*(int*)data); - len = sizeof(val); - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_SET_FINAL_COMPRESSION, &val, &len); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(final_format) -{ - int ret = SCANNER_ERR_OK; - SANE_FinalImgFormat ff; - unsigned int len = sizeof(ff); - - if (setv) - { - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_FINAL_IMAGE_FORMAT, &ff, &len); - if (ret == SANE_STATUS_GOOD) - { - int now = ff.img_format, init = SANE_IMAGE_TYPE_BMP; - std::vector all(sane_opt_trans::support_image_types()); - for (int i = 0; i < (int)all.size(); ++i) - { - value_role role = VAL_ROLE_NONE; - ff.img_format = (SANE_ImageType)all[i]; - if (ff.img_format == now) - role = VAL_ROLE_CURRENT; - if (ff.img_format == init) - role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&ff, role, VAL_LIMIT_ENUM, data)) - break; - } - } - } - else - { - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_SET_FINAL_IMAGE_FORMAT, data, &len); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(serial) -{ - int ret = SCANNER_ERR_INVALID_PARAMETER; - if (setv) - { - std::string val(""); - - ret = control_read_string(IO_CTRL_CODE_GET_SERIAL, val); - if (ret == SANE_STATUS_GOOD) - setv(&val, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, data); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(to_be_scan) -{ - int ret = SCANNER_ERR_OK; - SANE_Bool wait_paper = SANE_FALSE; - unsigned int len = sizeof(wait_paper); - - if (setv) - { - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_SCAN_WHEN_PAPER_ON, &wait_paper, &len); - if (ret == SANE_STATUS_GOOD) - { - bool val = wait_paper == SANE_TRUE; - - set_cur_and_def_value(val, false, setv, data); - } - } - else - { - wait_paper = *((bool*)data) ? SANE_TRUE : SANE_FALSE; - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_SET_SCAN_WHEN_PAPER_ON, &wait_paper, &len); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(scan_with_hole) -{ - int ret = SCANNER_ERR_OK; - SANE_Bool with_hole = SANE_FALSE; - unsigned int len = sizeof(with_hole); - - if (setv) - { - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_SCAN_WITH_HOLE, &with_hole, &len); - if (ret == SANE_STATUS_GOOD) - { - bool val = with_hole == SANE_TRUE; - - set_cur_and_def_value(val, false, setv, data); - } - } - else - { - with_hole = *((bool*)data) ? SANE_TRUE : SANE_FALSE; - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_SET_SCAN_WITH_HOLE, &with_hole, &len); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(device_code) -{ - int ret = SCANNER_ERR_INVALID_PARAMETER; - if (setv) - { - std::string val(""); - - ret = control_read_string(IO_CTRL_CODE_GET_DEVICE_CODE, val); - if (ret == SANE_STATUS_GOOD) - setv(&val, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, data); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(power) -{ - int ret = SCANNER_ERR_OK; - - if (setv) - { - SANE_Power now = SANE_POWER_MINUTES_30, init = SANE_POWER_MINUTES_30; - unsigned int len = sizeof(now); - - hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_POWER_LEVEL, &now, &len); - for (int i = SANE_POWER_FIRST; i < SANE_POWER_LAST; ++i) - { - value_role role = VAL_ROLE_NONE; - if (i == now) - role = VAL_ROLE_CURRENT; - if (i == init) - role = value_role(role | VAL_ROLE_DEFAULT); - - SANE_Power power = (SANE_Power)i; - if (!setv(&power, role, VAL_LIMIT_ENUM, data)) - break; - } - } - else - { - SANE_Power power = *((SANE_Power*)data); - unsigned int len = sizeof(power); - ret = hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_SET_POWER_LEVEL, &power, &len); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(hardware_version) -{ - int ret = SCANNER_ERR_INVALID_PARAMETER; - if (setv) - { - std::string val(""); - - ret = control_read_string(IO_CTRL_CODE_GET_HARDWARE_VERSION, val); - if (ret == SANE_STATUS_GOOD) - setv(&val, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, data); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(ip) -{ - int ret = SCANNER_ERR_INVALID_PARAMETER; - if (setv) - { - std::string val(""); - - ret = control_read_string(IO_CTRL_CODE_GET_IP, val); - if (ret == SANE_STATUS_GOOD) - setv(&val, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, data); - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(erase_hole) -{ - int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - if (is_erase_hole_l_id_ != -1 || is_erase_hole_r_id_ != -1) - { - SANE_Bool yes = SANE_FALSE, def = SANE_FALSE; - SANE_Int after = 0; - if (setv) - { - if (is_erase_hole_l_id_ != -1) - { - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)is_erase_hole_l_id_, &yes); - hg_sane_middleware::instance()->get_def_value(handle_, (void*)is_erase_hole_l_id_, &def); - } - if (!yes && is_erase_hole_r_id_ != -1) - { - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)is_erase_hole_r_id_, &yes); - hg_sane_middleware::instance()->get_def_value(handle_, (void*)is_erase_hole_r_id_, &def); - } - - set_cur_and_def_value(yes == SANE_TRUE, def == SANE_TRUE, setv, data); - ret = SCANNER_ERR_OK; - } - else - { - yes = *(bool*)data ? SANE_TRUE : SANE_FALSE; - if (is_erase_hole_l_id_ != -1) - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)is_erase_hole_l_id_, SANE_ACTION_SET_VALUE, &yes, &after); - yes = *(bool*)data ? SANE_TRUE : SANE_FALSE; - if (is_erase_hole_r_id_ != -1) - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)is_erase_hole_r_id_, SANE_ACTION_SET_VALUE, &yes, &after); - } - } - - return ret; -} -EX_OPTION_HANDLER_IMPL(search_hole_range) -{ - int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - if (search_hole_range_l_id_ != -1 || search_hole_range_r_id_ != -1) - { - SANE_Fixed val = 0; - SANE_Int after = 0; - double rv = .0f, def = .0f; - if (setv) - { - const SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); - void* init = hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id), - * cur = hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id); - float n = SANE_UNFIX(*(SANE_Fixed*)cur), - d = SANE_UNFIX(*(SANE_Fixed*)init); - - if (desc->constraint_type == SANE_CONSTRAINT_RANGE) - { - float l = SANE_UNFIX(desc->constraint.range->min), - u = SANE_UNFIX(desc->constraint.range->max), - s = SANE_UNFIX(desc->constraint.range->quant); - set_value_range(*(SANE_Fixed*)cur, *(SANE_Fixed*)init, desc->constraint.range->min, desc->constraint.range->max, desc->constraint.range->quant, setv, data, &scanner::to_float); - } - else - set_cur_and_def_value(n, d, setv, data); - local_utility::free_memory(init); - local_utility::free_memory(cur); - - ret = SCANNER_ERR_OK; - } - else - { - rv = (double)*(float*)data; - val = SANE_FIX(rv); - if (search_hole_range_l_id_ != -1) - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)search_hole_range_l_id_, SANE_ACTION_SET_VALUE, &val, &after); - val = SANE_FIX(rv); - if (search_hole_range_r_id_ != -1) - ret = hg_sane_middleware::instance()->set_option(handle_, (void*)search_hole_range_r_id_, SANE_ACTION_SET_VALUE, &val, &after); - } - } - - return ret; -} - -// ISaneInvoker -COM_API_IMPLEMENT(scanner, int, start(void)) -{ - int ret = SANE_STATUS_GOOD; - - ev_cnt_ = 0; - events_.clear(); - images_.clear(); - scan_msg_ = "OK"; - scan_err_ = false; - user_cancel_ = false; - app_wnd_ = setting_.get() ? setting_->hwnd() : callback::find_main_wnd(); - ret = hg_sane_middleware::instance()->start(handle_, NULL); - - // the third-APPs in linux will call 'stop' after every start, but it not happens in windows-apps, so we handle this as following ... - if(ret == SANE_STATUS_NO_DOCS && prev_start_result_ == SANE_STATUS_GOOD) - ret = hg_sane_middleware::instance()->start(handle_, NULL); - - if (ret == SANE_STATUS_GOOD) - { - if (indicator_.get() && !IsWindowVisible(indicator_->hwnd())) - indicator_->show(true); - - unsigned int l = sizeof(img_fmt_); - SANE_CompressionType cmprsn = img_fmt_.compress.compression; - if (hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_FINAL_IMAGE_FORMAT, &img_fmt_, &l)) - img_fmt_.img_format = SANE_IMAGE_TYPE_BMP; - img_fmt_.compress.compression = cmprsn; - } - //else if (indicator_.get()) - //{ - // indicator_->notify_scan_over(hg_scanner_err_description(ret), true); - //} - else - { - std::wstring msg(local_trans::a2u(hg_scanner_err_description(ret), CP_UTF8)); - - if (indicator_.get()) - indicator_->show(false); - if (!IsWindow(app_wnd_)) - callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_START_FAILED).c_str()); - MessageBoxW(app_wnd_, msg.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_START_FAILED).c_str(), MB_OK | MB_ICONERROR); - } - prev_start_result_ = ret; - is_scanning_ = ret == SANE_STATUS_GOOD; - - return local_utility::sane_statu_2_scanner_err(ret); -} -COM_API_IMPLEMENT(scanner, int, stop(void)) -{ - user_cancel_ = true; - return hg_sane_middleware::instance()->stop(handle_); -} -COM_API_IMPLEMENT(scanner, int, get_event(void)) -{ - return events_.take(); -} -COM_API_IMPLEMENT(scanner, void, set_event_callback(int(__stdcall* handle_ev)(int, void*), void* para)) -{ - scanner_ev_handler_ = handle_ev; - evh_param_ = para; -} -COM_API_IMPLEMENT(scanner, bool, wait_image(DWORD milliseconds)) -{ - int count = get_scanned_images(milliseconds); - - return count > 0; -} -COM_API_IMPLEMENT(scanner, int, get_scanned_images(DWORD milliseconds)) -{ - size_t count = images_.count(); - DWORD elapse = 10; - - is_ui_wait_img_ = true; - while (is_scanning_ && count == 0 && milliseconds) - { - MSG msg = { 0 }; - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - else - Sleep(elapse); - - int ev = get_event(); - - count = images_.count(); - if (ev == SANE_EVENT_SCAN_FINISHED) - { - ui_hide(); - break; - } - else if (ev == SANE_EVENT_UI_CLOSE_CANCEL) - { - stop(); - ui_hide(); - break; - } - else if (ev == SANE_EVENT_UI_CLOSE_NORMAL) - { - ui_hide(); - break; - } - if (milliseconds != -1) - { - if (milliseconds <= elapse) - break; - - milliseconds -= elapse; - } - } - is_ui_wait_img_ = false; - count = images_.count(); - - { - wchar_t msg[128] = { 0 }; - swprintf_s(msg, _countof(msg) - 1, L"Wait image count = %d\r\n", count); - log_info(msg, 0); - } - - return count; -} -COM_API_IMPLEMENT(scanner, IScanImg*, take_first_image(twain_xfer xfer)) -{ - scanned_img* img = images_.take(); - - return dynamic_cast(img); -} -COM_API_IMPLEMENT(scanner, bool, get_first_image_header(SANE_Parameters* header, size_t* bytes, int* dpi)) -{ - return images_.get_header(header, bytes, dpi); -} -COM_API_IMPLEMENT(scanner, bool, is_online(void)) -{ - std::string sn(""); - - return handle_ && control_read_string(IO_CTRL_CODE_GET_SERIAL, sn) != SCANNER_ERR_DEVICE_NOT_FOUND; -} -COM_API_IMPLEMENT(scanner, bool, is_paper_on(void)) -{ - SANE_Bool on = SANE_FALSE; - unsigned int len = sizeof(on); - - if (hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_PAPER_ON, &on, &len) == SANE_STATUS_GOOD) - return on == SANE_TRUE; - else - return false; -} -COM_API_IMPLEMENT(scanner, int, last_error(void)) -{ - return err_; -} - -COM_API_IMPLEMENT(scanner, bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes)) -{ - EXAPIPOS ex = find_ex_api(sn); - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, ex == ex_opts_.end() ? (void*)sn : (void*)ex->base_ind); - bool ret = false; - - if (desc) - { - if (type) - *type = scanner::from_sane_type(desc->type); - if (limit) - *limit = scanner::from_sane_constraint(desc->constraint_type); - if (bytes) - *bytes = desc->size; - - ret = true; - } - - return ret; -} -COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* param)) -{ - EXAPIPOS ex = find_ex_api(sn); - int ret = SANE_STATUS_INVAL; - SANE_Int after = 0; - - if (ex == ex_opts_.end()) - { - if (get_option_value_with_parent(sn, setval, param)) - return true; - - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)sn); - void* init = hg_sane_middleware::instance()->get_def_value(handle_, (void*)sn); - ret = SANE_STATUS_GOOD; - if (desc->type == SANE_TYPE_BOOL) - { - SANE_Bool v = SANE_FALSE; - bool val = false; - - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)sn, &v); - val = v == SANE_TRUE; - //set_cur_and_def_value(val, *(SANE_Bool*)init == SANE_TRUE, setval, param); - { - int role = VAL_ROLE_NONE; - val = false; - if (*(SANE_Bool*)init == SANE_FALSE) - role |= VAL_ROLE_DEFAULT; - if (v == SANE_FALSE) - role |= VAL_ROLE_CURRENT; - setval(&val, (value_role)role, VAL_LIMIT_ENUM, param); - val = true; - role = VAL_ROLE_NONE; - if (*(SANE_Bool*)init == SANE_TRUE) - role |= VAL_ROLE_DEFAULT; - if (v == SANE_TRUE) - role |= VAL_ROLE_CURRENT; - setval(&val, (value_role)role, VAL_LIMIT_ENUM, param); - } - } - else if (desc->type == SANE_TYPE_INT) - { - SANE_Int cur = 0, def = *(SANE_Int*)init; - int val = 0; - - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)sn, &cur); - val = cur; - if (sn == resolution_id_) - dpi_ = cur; - do - { - if (desc->constraint_type == SANE_CONSTRAINT_RANGE) - { - set_value_range(cur, def, desc->constraint.range->min, desc->constraint.range->max, desc->constraint.range->quant, setval, param, scanner::to_int); - } - else if (desc->constraint_type == SANE_CONSTRAINT_WORD_LIST) - { - const SANE_Word* v = desc->constraint.word_list; - for (int i = 0; i < v[0]; ++i) - { - value_role role = VAL_ROLE_NONE; - if (v[i + 1] == cur) - role = value_role(role | VAL_ROLE_CURRENT); - if (v[i + 1] == *(SANE_Int*)init) - role = value_role(role | VAL_ROLE_DEFAULT); - val = v[i + 1]; - if (!setval(&val, role, VAL_LIMIT_ENUM, param)) - break; - } - } - else - set_cur_and_def_value(val, *(SANE_Int*)init, setval, param); - - }while (0); - } - else if (desc->type == SANE_TYPE_FIXED) - { - SANE_Fixed cur = 0, def = *(SANE_Fixed*)init; - float val = .0f; - - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)sn, &cur); - if (sn == resolution_id_) - dpi_ = (int)(SANE_UNFIX(cur) + .5f); - do - { - if (desc->constraint_type == SANE_CONSTRAINT_RANGE) - { - set_value_range(cur, def, desc->constraint.range->min, desc->constraint.range->max, desc->constraint.range->quant, setval, param, scanner::to_float); - } - else if (desc->constraint_type == SANE_CONSTRAINT_WORD_LIST) - { - const SANE_Word* v = desc->constraint.word_list; - for (int i = 0; i < v[0]; ++i) - { - value_role role = VAL_ROLE_NONE; - if (v[i + 1] == cur) - role = value_role(role | VAL_ROLE_CURRENT); - if (v[i + 1] == def) - role = value_role(role | VAL_ROLE_DEFAULT); - val = (float)SANE_UNFIX(v[i + 1]); - if (!setval(&val, role, VAL_LIMIT_ENUM, param)) - break; - } - } - else - set_cur_and_def_value(val, (float)SANE_UNFIX(*(SANE_Fixed*)init), setval, param); - } while (0); - } - else if (desc->type == SANE_TYPE_STRING) - { - char* buf = new char[desc->size + 4]; - std::string val(""), def((char*)init); - - memset(buf, 0, desc->size + 4); - hg_sane_middleware::instance()->get_cur_value(handle_, (void*)sn, buf); - val = buf; - do - { - if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) - { - for (int i = 0; desc->constraint.string_list[i]; ++i) - { - value_role role = VAL_ROLE_NONE; - if (strcmp(desc->constraint.string_list[i], buf) == 0) - role = value_role(role | VAL_ROLE_CURRENT); - if (strcmp(desc->constraint.string_list[i], (char*)init) == 0) - role = value_role(role | VAL_ROLE_DEFAULT); - - val = desc->constraint.string_list[i]; - if (!setval(&val, role, VAL_LIMIT_ENUM, param)) - break; - } - } - else - set_cur_and_def_value(val, def, setval, param); - } while (0); - delete[] buf; - } - else - { - ret = SANE_STATUS_INVAL; - } - local_utility::free_memory(init); - } - else - { - ret = (this->*ex->ex_api)(ex->base_ind, param, setval); - } - - return ret == SANE_STATUS_GOOD; -} -COM_API_IMPLEMENT(scanner, int, set_value(int sn, void* val)) -{ - EXAPIPOS ex = find_ex_api(sn); - int ret = SANE_STATUS_INVAL; - SANE_Int after = 0; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)sn); - - { - wchar_t msg[256] = { 0 }; - if (ex == ex_opts_.end()) - swprintf_s(msg, _countof(msg) - 1, L"set_value of %s(%s) of ID %d\r\n", local_trans::a2u(desc->name, CP_UTF8).c_str(), local_trans::a2u(hg_sane_middleware::option_value_2_string(desc->type, val).c_str(), CP_UTF8).c_str(), sn); - else if(ex->base_ind != -1) - { - desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)ex->base_ind); - swprintf_s(msg, _countof(msg) - 1, L"set_value of %s(0x%x) of ID %d, base id = %d)\r\n", local_trans::a2u(desc->name, CP_UTF8).c_str(), *(unsigned*)val, sn, ex->base_ind); - } - log_info(msg, 0); - } - - twain_set_ = true; - if (ex == ex_opts_.end()) - { - if (!set_option_value_with_parent(sn, val, &ret)) - ret = set_option_value(sn, desc->type, desc->size, val); - ret = local_utility::sane_statu_2_scanner_err(ret); - } - else - { - ret = (this->*ex->ex_api)(ex->base_ind, val, NULL); - } - - if (sn == resolution_id_) - { - if (desc->type == SANE_TYPE_FIXED) - dpi_ = (int)(*(float*)val + .5f); - else - dpi_ = *(int*)val; - } - - return ret; -} -COM_API_IMPLEMENT(scanner, int, convert_image(SANE_ImageFormatConvert* conv)) -{ - return hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_CONVERT_IMAGE_FORMAT, conv, NULL); -} -COM_API_IMPLEMENT(scanner, void, free_buffer(void* buf, int len)) -{ - hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_FREE_MEMORY, buf, (unsigned int*)&len); -} - -// SANE options ID ... -SANE_OPTION_ID_IMPLEMENT(color_correction) -SANE_OPTION_ID_IMPLEMENT(fold_type) -SANE_OPTION_ID_IMPLEMENT(is_multiout) -SANE_OPTION_ID_IMPLEMENT(multiout_type) -SANE_OPTION_ID_IMPLEMENT(color_mode) -SANE_OPTION_ID_IMPLEMENT(erase_color) -SANE_OPTION_ID_IMPLEMENT(erase_multiout_red) -SANE_OPTION_ID_IMPLEMENT(erase_paper_red) -SANE_OPTION_ID_IMPLEMENT(is_erase_background) -SANE_OPTION_ID_IMPLEMENT(background_color_range) -SANE_OPTION_ID_IMPLEMENT(sharpen) -SANE_OPTION_ID_IMPLEMENT(erase_morr) -SANE_OPTION_ID_IMPLEMENT(erase_grids) -SANE_OPTION_ID_IMPLEMENT(error_extend) -SANE_OPTION_ID_IMPLEMENT(is_noise_modify) -SANE_OPTION_ID_IMPLEMENT(noise_threshold) -SANE_OPTION_ID_IMPLEMENT(paper) -SANE_OPTION_ID_IMPLEMENT(is_custom_area) -SANE_OPTION_ID_IMPLEMENT(curstom_area_l) -SANE_OPTION_ID_IMPLEMENT(curstom_area_r) -SANE_OPTION_ID_IMPLEMENT(curstom_area_t) -SANE_OPTION_ID_IMPLEMENT(curstom_area_b) -SANE_OPTION_ID_IMPLEMENT(is_size_check) -SANE_OPTION_ID_IMPLEMENT(page) -SANE_OPTION_ID_IMPLEMENT(blank_page_threshold) -SANE_OPTION_ID_IMPLEMENT(resolution) -SANE_OPTION_ID_IMPLEMENT(image_quality) -SANE_OPTION_ID_IMPLEMENT(is_swap) -SANE_OPTION_ID_IMPLEMENT(is_split) -SANE_OPTION_ID_IMPLEMENT(is_auto_deskew) -SANE_OPTION_ID_IMPLEMENT(is_custom_gamma) -SANE_OPTION_ID_IMPLEMENT(bright) -SANE_OPTION_ID_IMPLEMENT(contrast) -SANE_OPTION_ID_IMPLEMENT(gamma) -SANE_OPTION_ID_IMPLEMENT(is_erase_black_frame) -SANE_OPTION_ID_IMPLEMENT(deep_sample) -SANE_OPTION_ID_IMPLEMENT(threshold) -SANE_OPTION_ID_IMPLEMENT(anti_noise) -SANE_OPTION_ID_IMPLEMENT(margin) -SANE_OPTION_ID_IMPLEMENT(fill_background) -SANE_OPTION_ID_IMPLEMENT(is_anti_permeate) -SANE_OPTION_ID_IMPLEMENT(anti_permeate_level) -SANE_OPTION_ID_IMPLEMENT(is_erase_hole) -SANE_OPTION_ID_IMPLEMENT(search_hole_range) -SANE_OPTION_ID_IMPLEMENT(is_filling_color) -SANE_OPTION_ID_IMPLEMENT(is_ultrasonic_check) -SANE_OPTION_ID_IMPLEMENT(is_check_staple) -SANE_OPTION_ID_IMPLEMENT(scan_mode) -SANE_OPTION_ID_IMPLEMENT(scan_count) -SANE_OPTION_ID_IMPLEMENT(text_direction) -SANE_OPTION_ID_IMPLEMENT(is_rotate_bkg180) -SANE_OPTION_ID_IMPLEMENT(is_check_dogear) -SANE_OPTION_ID_IMPLEMENT(dogear_size) -SANE_OPTION_ID_IMPLEMENT(is_check_skew) -SANE_OPTION_ID_IMPLEMENT(skew_range) -SANE_OPTION_ID_IMPLEMENT(black_white_threshold) -SANE_OPTION_ID_IMPLEMENT(is_photo_mode) -SANE_OPTION_ID_IMPLEMENT(double_feed_handle) -SANE_OPTION_ID_IMPLEMENT(scan_when_paper_on) -SANE_OPTION_ID_IMPLEMENT(feed_strength) -SANE_OPTION_ID_IMPLEMENT(power_scheme) -SANE_OPTION_ID_IMPLEMENT(is_auto_strength) -SANE_OPTION_ID_IMPLEMENT(feed_strength_value) -SANE_OPTION_ID_IMPLEMENT(is_reverse_bw) -SANE_OPTION_ID_IMPLEMENT(is_erase_hole_l) -SANE_OPTION_ID_IMPLEMENT(search_hole_range_l) -SANE_OPTION_ID_IMPLEMENT(is_erase_hole_r) -SANE_OPTION_ID_IMPLEMENT(search_hole_range_r) -SANE_OPTION_ID_IMPLEMENT(is_erase_hole_t) -SANE_OPTION_ID_IMPLEMENT(search_hole_range_t) -SANE_OPTION_ID_IMPLEMENT(is_erase_hole_b) -SANE_OPTION_ID_IMPLEMENT(search_hole_range_b) -SANE_OPTION_ID_IMPLEMENT(fold_direction) - -// SANE-ex option ID: -SANE_OPTION_ID_IMPLEMENT(ex_multiout_type) -SANE_OPTION_ID_IMPLEMENT(ex_auto_color_type) -SANE_OPTION_ID_IMPLEMENT(ex_color_mode) -SANE_OPTION_ID_IMPLEMENT(ex_sharpen) -SANE_OPTION_ID_IMPLEMENT(ex_paper) -SANE_OPTION_ID_IMPLEMENT(ex_paper_lateral) -SANE_OPTION_ID_IMPLEMENT(ex_auto_paper_size) -SANE_OPTION_ID_IMPLEMENT(ex_is_paper_auto_crop) -SANE_OPTION_ID_IMPLEMENT(ex_text_direction) -SANE_OPTION_ID_IMPLEMENT(ex_duplex) -SANE_OPTION_ID_IMPLEMENT(ex_fill_background) -SANE_OPTION_ID_IMPLEMENT(ex_discard_blank_page) -SANE_OPTION_ID_IMPLEMENT(ex_discard_blank_receipt) -SANE_OPTION_ID_IMPLEMENT(ex_is_page_fold) -SANE_OPTION_ID_IMPLEMENT(ex_color_filter) -SANE_OPTION_ID_IMPLEMENT(ex_color_enhance) -SANE_OPTION_ID_IMPLEMENT(ex_final_compression) -SANE_OPTION_ID_IMPLEMENT(ex_final_format) -SANE_OPTION_ID_IMPLEMENT(ex_serial) -SANE_OPTION_ID_IMPLEMENT(ex_to_be_scan) -SANE_OPTION_ID_IMPLEMENT(ex_scan_with_hole) -SANE_OPTION_ID_IMPLEMENT(ex_device_code) -SANE_OPTION_ID_IMPLEMENT(ex_power) -SANE_OPTION_ID_IMPLEMENT(ex_hardware_version) -SANE_OPTION_ID_IMPLEMENT(ex_ip) - -COM_API_IMPLEMENT(scanner, void, twain_set_transfer(twain_xfer xfer)) -{ - xfer_ = xfer; -} -COM_API_IMPLEMENT(scanner, void, twain_set_compression(SANE_CompressionType compression, void* detail)) -{ - img_fmt_.compress.compression = compression; - img_fmt_.compress.detail = detail; -} -COM_API_IMPLEMENT(scanner, int, twain_get_config(char* buf, size_t* len)) -{ - if (cfg_) - { - std::string cont(cfg_->to_text_stream()); - - if (*len < cont.length()) - { - *len = cont.length() + 4; - - return SCANNER_ERR_INSUFFICIENT_MEMORY; - } - strcpy(buf, cont.c_str()); - } - - return SCANNER_ERR_OK; -} -COM_API_IMPLEMENT(scanner, int, twain_set_config(char* buf, size_t len)) -{ - if(cfg_ && cfg_->load_mem(buf)) - { - update_config(); - apply_config(); - - return SCANNER_ERR_OK; - } - - return SCANNER_ERR_DATA_DAMAGED; -} - - -// ui ... -COM_API_IMPLEMENT(scanner, bool, ui_show_main(HWND parent)) -{ - return false; -} -COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan, bool indicator)) -{ - if (callback::show_setting_ui) - { - auto cb = [&](int ev) - { - on_ui_event(ev, NULL); - }; - callback::show_setting_ui(handle_, parent, &sane_api_, with_scan, cb); - } - else if (cfg_) - { - if (with_scan) - { - events_.clear(); - images_.clear(); - scan_msg_ = "OK"; - scan_err_ = false; - } - - size_t pid = scanner_name_.find(L" - "); - if (pid == -1) - pid = scanner_name_.length(); - setting_.reset(new dlg_setting(parent, &sane_api_, handle_, with_scan, scanner_name_.substr(0, pid).c_str())); - setting_->set_ui_event_notify(&scanner::ui_callback, this); - setting_->set_config(cfg_, (cfg_path_ + scanner_name_.substr(0, pid) + L".cfg").c_str(), &scanner::apply_scheme, this, &twain_set_); - indicator_.reset(); - if (indicator) - { - indicator_.reset(new dlg_indicator(setting_->hwnd())); - indicator_->set_ui_event_notify(&scanner::ui_callback, this); - } - setting_->show(true); - } - - return true; -} -COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent)) -{ - if (callback::show_progress_ui) - { - } - else - { - if (setting_.get() && IsWindowVisible(setting_->hwnd())) - parent = setting_->hwnd(); - else if (!IsWindow(parent)) - parent = callback::find_main_wnd(); - - indicator_.reset(new dlg_indicator(parent)); - indicator_->set_ui_event_notify(&scanner::ui_callback, this); - indicator_->show(true); - } - - return true; -} -COM_API_IMPLEMENT(scanner, void, ui_hide(void)) -{ - if (indicator_.get()) - indicator_.reset(); - if (setting_.get()) - setting_.reset(); -} -COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void)) -{ - return true; -} - - - -// called from device-layer ... -int scanner::handle_device_event(int ev_code, void* data, unsigned int* len) -{ - if (ev_code == SANE_EVENT_WORKING) - { - if (indicator_.get()) - indicator_->notify_working(); - else - on_ui_event(ev_code, (void*)ev_code); - - log_info(L"Scanning ...\r\n", 0); - } - else if (ev_code == SANE_EVENT_IMAGE_OK) - { - SANE_Image* simg = (SANE_Image*)data; - scanned_img* img = NULL; - wchar_t name[40] = { 0 }; - - swprintf_s(name, _countof(name) - 1, L"img_%05u.bmp", ++img_ind_); - img = new scanned_img(handle_, simg->header, simg->data, simg->bytes, simg->flag.dpi, (tmp_path_ + name).c_str(), xfer_, &img_fmt_); - if (img->bytes() /*>= simg->bytes*/) - { - size_t bytes = 0; - int times = 0; - - images_.count(&bytes); - img->set_image_status((SANE_Image_Statu)simg->flag.statu); - bytes /= 1024 * 1024; - while (bytes > max_img_mem_ && !user_cancel_ && times++ < 20) // memory control - { - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - images_.count(&bytes); - bytes /= 1024 * 1024; - if (times == 1) - log_info(L"Memory usage upto limit! wait up to 100 ms ...\r\n", 0); - } - images_.save(img, img->bytes()); - } - else - { - img->release(); - } - if (indicator_.get()) - indicator_->notify_data_arrived(true); - - { - wchar_t msg[128] = { 0 }; - swprintf_s(msg, _countof(msg) - 1, L"New image(%u) received with %u bytes\r\n", img_ind_, simg->bytes); - log_info(msg, 0); - } - } - else if (ev_code == SANE_EVENT_USB_DATA_RECEIVED) - { - if (indicator_.get()) - indicator_->notify_data_arrived(false); - } - else if (ev_code == SANE_EVENT_SCAN_FINISHED) - { - err_ = *len; - if (indicator_.get()) - indicator_->notify_scan_over((char*)data, *len != SCANNER_ERR_OK); - else - { - if (*len) - { - std::wstring msg(local_trans::a2u((char*)data, CP_UTF8)); - if(!IsWindow(app_wnd_)) - callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str()); - MessageBoxW(app_wnd_, msg.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str(), MB_OK); - } - on_ui_event(ev_code, (void*)ev_code); - } - // is_scanning_ = false; - - { - wchar_t msg[128] = { 0 }; - swprintf_s(msg, _countof(msg) - 1, L"Scan finished with error: %u\r\n", *len); - log_info(msg, 0); - } - } - - return 0; -} - - - - - - - - - - - - - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// log ... -#include - -std::mutex g_lock_; -std::string g_path_file_(""); -FILE* g_file_ = NULL; - -void init_log(void) -{ - char* tmp = getenv("LOCALAPPDATA"); - if (tmp) - { - std::string path(tmp); - char name[MAX_PATH] = { 0 }, * last = NULL; - - path += std::string("\\") + PRODUCT_VENDOR + "Scan\\Log\\"; - mkdir(path.c_str()); - GetModuleFileNameA(NULL, name, _countof(name) - 1); - last = strrchr(name, '\\'); - if (last++ == NULL) - last = name; - path += last; - path += "_twain.log"; - g_file_ = fopen(path.c_str(), "a+b"); - g_path_file_ = path; - } - else - { - char name[MAX_PATH] = { 0 }, * last = NULL; - std::string path(""); - - GetModuleFileNameA(NULL, name, _countof(name) - 1); - path = std::string(name) + "_twain.log"; - g_file_ = fopen(path.c_str(), "a+b"); - g_path_file_ = path; - } - if (g_file_) - { - fseek(g_file_, 0, SEEK_END); - if (ftell(g_file_)) - { - std::wstring sep(L"\r\n\r\n\r\n=======================================================\r\n"); - fwrite(sep.c_str(), 2, sep.length(), g_file_); - } - else - { - unsigned short bom = 0x0feff; - fwrite(&bom, sizeof(bom), 1, g_file_); - } - - wchar_t ts[128] = { 0 }, now[40] = { 0 }; - - hg_get_current_time_w(now); - swprintf_s(ts, _countof(ts) - 1, L"==================%s==================\r\n", now); - fwrite(ts, 2, lstrlenW(ts), g_file_); - } -} -void close_log(void) -{ - if (g_file_) - fclose(g_file_); - g_file_ = NULL; -} -void log(const wchar_t* info) -{ - if (g_file_) - { - std::lock_guard lock(g_lock_); - - fwrite(info, 2, lstrlenW(info), g_file_); - fflush(g_file_); - if (ftell(g_file_) > 10 * 1024 * 1024) - { - fclose(g_file_); - remove(g_path_file_.c_str()); - g_file_ = fopen(g_path_file_.c_str(), "a+b"); - if (g_file_) - { - unsigned short bom = 0x0feff; - wchar_t ts[128] = { 0 }, now[40] = { 0 }; - - hg_get_current_time_w(now); - swprintf_s(ts, _countof(ts) - 1, L"==================%s (Truncated when size > 10MB) ==================\r\n", now); - fwrite(&bom, sizeof(bom), 1, g_file_); - fwrite(ts, 2, lstrlenW(ts), g_file_); - } - } - } -} - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// exports -extern "C" -{ -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - int __stdcall initialize(void* reserve) - { - init_log(); - callback::init_ui(); - - hg_sane_middleware::set_callback(callback::sane_event_callback, NULL); - if (hg_sane_middleware::instance()->is_ready()) - return SANE_STATUS_GOOD; - else - return SCANNER_ERR_LANG_PAK_LOST; - } -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - int __stdcall open_scanner(SCANNERID scanner_id, ISaneInvoker** invoker) - { - if (!invoker) - return SCANNER_ERR_INVALID_PARAMETER; - - if (!is_scanner_online(scanner_id)) - return SCANNER_ERR_DEVICE_NOT_FOUND; - - scanner* scn = new scanner(scanner_id); - if (scn->last_error() == SCANNER_ERR_OK) - { - *invoker = dynamic_cast(scn); - - return 0; - } - else - { - int ret = scn->last_error(); - - scn->release(); - *invoker = NULL; - - return ret; - } - } -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - bool __stdcall is_scanner_online(SCANNERID scanner_id) - { - std::vector que; - - scanner::get_scanner_name(scanner_id, que); - - return !que.empty(); - } -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - int __stdcall uninitialize(void* reserve) - { - hg_sane_middleware::set_callback(NULL, NULL); - hg_sane_middleware::clear(); - close_log(); - - return 0; - } -#ifdef EXPORT_SANE_API - __declspec(dllexport) -#else - __declspec(dllimport) -#endif - void __stdcall log_info(const wchar_t* info, int level) - { - log(info); - } - -} diff --git a/sane/scanner.h b/sane/scanner.h deleted file mode 100644 index 59fab90..0000000 --- a/sane/scanner.h +++ /dev/null @@ -1,330 +0,0 @@ -#pragma once - -#include "scanned_img.h" -#include -#include -#include - -#define SANE_OPTION_ID(name) \ - SANE_OPTION_ID_OVERRIDE(name); \ - int name##_id_ = -1; -#define SANE_OPTION_ID_IMPLEMENT(name) \ - SANE_OPTION_IMPLEMENT(scanner, name) \ - { \ - return name##_id_; \ - } - -#define EX_HANDLER_PROTO(name) \ - int name(int base_id, void* data, set_opt_value setv) -#define EX_OPTION_HANDLER_DECL(name) EX_HANDLER_PROTO(handle_ex_##name) -#define EX_OPTION_HANDLER_IMPL(name) EX_HANDLER_PROTO(scanner::handle_ex_##name) - -#define EXTENSION_ID_BASE 0x300 - -#include "DlgPage.h" -class dlg_indicator; -class dlg_setting; -namespace gb -{ - class scanner_cfg; -} - -class scanner : public ISaneInvoker, virtual public refer -{ - SANE_Handle handle_; - SCANNERID id_; - int err_; - int ex_id_; - int prev_start_result_; - int dpi_; - unsigned int img_ind_; - std::wstring scanner_name_; - std::wstring tmp_path_; - std::wstring cfg_path_; - std::string scan_msg_; - bool scan_err_; - volatile bool is_ui_wait_img_; - volatile bool is_scanning_; - volatile bool user_cancel_; - twain_xfer xfer_; - safe_img_queue images_; - size_t max_img_mem_; - safe_queue events_; //如果有界面,则全部保存从界面传回的消息;否则只保存开始扫描和结束扫描的事件 - int ev_cnt_; - SANE_FinalImgFormat img_fmt_; - std::unique_ptr indicator_; - std::unique_ptr setting_; - gb::scanner_cfg* cfg_; - bool twain_set_; - SANEAPI sane_api_; - - int(__stdcall* scanner_ev_handler_)(int, void*); - void* evh_param_; - HWND app_wnd_; // for MessageBox - - void transport_config_file(void); - void update_config(void); - void load_config(const wchar_t* file); - void save_config(const wchar_t* file); - void apply_config(void); - void on_ui_event(int uev, void* sender); - std::string choose_scanner(const std::vector& scanners); - int open(void); - int close(void); - int init_options_id(void); - int control_read_string(int code, std::string& ret); - - void extension_none(int id); - void extension_multiout_type(int id); - void extension_color_mode(int id); - void extension_sharpen(int id); - void extension_paper(int id); - void extension_fill_bkg_method(int id); - void extension_text_direction(int id); - void extension_page(int id); - void extension_erase_color(int id); - - bool get_option_value_with_parent(int sn, set_opt_value setv, void* param); // return true if handled - bool set_option_value_with_parent(int sn, void* data, int* err); // return true if handled sn - int set_option_value(int sn, SANE_Value_Type type, int size, void* data); - int set_is_multiout(bool enable); - - typedef struct _ex_api - { - unsigned int ind; - unsigned int base_ind; - int(scanner::* ex_api)(int, void*, set_opt_value); - bool operator==(const int& id) - { - return ind == id; - } - }EXAPI; - std::vector ex_opts_; - typedef std::vector::iterator EXAPIPOS; - EXAPIPOS find_ex_api(int op_id); - void apply_scheme(gb::sane_config_schm* schm); -; - EX_OPTION_HANDLER_DECL(multiout); - EX_OPTION_HANDLER_DECL(auto_color_type); - EX_OPTION_HANDLER_DECL(color_mode); - EX_OPTION_HANDLER_DECL(sharpen); // int - EX_OPTION_HANDLER_DECL(paper); - EX_OPTION_HANDLER_DECL(paper_lateral); - EX_OPTION_HANDLER_DECL(auto_paper_size); - EX_OPTION_HANDLER_DECL(auto_paper_crop); - EX_OPTION_HANDLER_DECL(text_direction); - EX_OPTION_HANDLER_DECL(duplex); - EX_OPTION_HANDLER_DECL(fill_background); // bool true - 凸多边形 - EX_OPTION_HANDLER_DECL(discard_blank_page); - EX_OPTION_HANDLER_DECL(discard_blank_receipt); - EX_OPTION_HANDLER_DECL(page_fold); - EX_OPTION_HANDLER_DECL(color_filter); - EX_OPTION_HANDLER_DECL(color_enhance); - - EX_OPTION_HANDLER_DECL(final_compression); // int - EX_OPTION_HANDLER_DECL(final_format); // SANE_FinalImgFormat - EX_OPTION_HANDLER_DECL(serial); // std::string - EX_OPTION_HANDLER_DECL(to_be_scan); // bool - EX_OPTION_HANDLER_DECL(scan_with_hole); // bool - EX_OPTION_HANDLER_DECL(device_code); // std::string - EX_OPTION_HANDLER_DECL(power); // int - EX_OPTION_HANDLER_DECL(hardware_version); // std::string - EX_OPTION_HANDLER_DECL(ip); // std::string - EX_OPTION_HANDLER_DECL(erase_hole); - EX_OPTION_HANDLER_DECL(search_hole_range); - - - template - bool set_cur_and_def_value(T cur, T def, set_opt_value setv, void* param) - { - if (cur == def) - return setv(&cur, (value_role)(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), VAL_LIMIT_NONE, param); - else if (setv(&cur, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, param)) - return setv(&def, VAL_ROLE_DEFAULT, VAL_LIMIT_NONE, param); - - return false; - } - template - void set_value_range(S cur, S def, S l, S u, S s, set_opt_value setv, void* param, T(__stdcall* to_t)(S)) - { - T v = to_t(cur); - while (setv(&v, VAL_ROLE_CURRENT, VAL_LIMIT_RANGE, param)) - { - v = to_t(def); - if (!setv(&v, VAL_ROLE_DEFAULT, VAL_LIMIT_RANGE, param)) - break; - - v = to_t(l); - if (!setv(&v, VAL_ROLE_LOWER, VAL_LIMIT_RANGE, param)) - break; - v = to_t(u); - if (!setv(&v, VAL_ROLE_UPPER, VAL_LIMIT_RANGE, param)) - break; - v = to_t(s); - setv(&v, VAL_ROLE_STEP, VAL_LIMIT_RANGE, param); - - break; - } - } - - static int __stdcall to_int(SANE_Int v); - static float __stdcall to_float(SANE_Fixed v); - static void __stdcall ui_callback(int uev, void* sender, void* param); - static bool is_option_float(int sn, void* param); - static void __stdcall apply_scheme(gb::sane_config_schm* schm, void* param); - -public: - scanner(SCANNERID id); -protected: - ~scanner(); - -public: - static bool is_belong_serial(int vid, int pid, SCANNERID serial); - static void get_scanner_name(SCANNERID id, std::vector& names); - static value_type from_sane_type(SANE_Value_Type type); - static value_limit from_sane_constraint(SANE_Constraint_Type type); - static int control_read_string(SANE_Handle hdev, int code, std::string& str); - - // IRef -public: - COM_API_OVERRIDE(long, add_ref(void)); - COM_API_OVERRIDE(long, release(void)); - - // ISaneInvoker -public: - COM_API_OVERRIDE(int, start(void)); - COM_API_OVERRIDE(int, stop(void)); - COM_API_OVERRIDE(int, get_event(void)); - COM_API_OVERRIDE(void, set_event_callback(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL)); - COM_API_OVERRIDE(bool, wait_image(DWORD milliseconds = -1)); - COM_API_OVERRIDE(int, get_scanned_images(DWORD milliseconds = 0)); - COM_API_OVERRIDE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz - COM_API_OVERRIDE(bool, get_first_image_header(SANE_Parameters* header, size_t* bytes = NULL, int* dpi = NULL)); - COM_API_OVERRIDE(bool, is_online(void)); - COM_API_OVERRIDE(bool, is_paper_on(void)); - COM_API_OVERRIDE(int, last_error(void)); - COM_API_OVERRIDE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes)); - COM_API_OVERRIDE(bool, get_value(int sn, set_opt_value, void* param)); - COM_API_OVERRIDE(int, set_value(int sn, void* val)); - COM_API_OVERRIDE(int, convert_image(SANE_ImageFormatConvert* conv)); - COM_API_OVERRIDE(void, free_buffer(void* buf, int len)); - - // SANE options ID ... - SANE_OPTION_ID(color_correction); // 2023-02-24 15:31:19 色偏校正 - SANE_OPTION_ID(fold_type); // 2023-02-24 15:28:46 对折模式 - SANE_OPTION_ID(is_multiout); - SANE_OPTION_ID(multiout_type); - SANE_OPTION_ID(color_mode); - SANE_OPTION_ID(erase_color); - SANE_OPTION_ID(erase_multiout_red); - SANE_OPTION_ID(erase_paper_red); - SANE_OPTION_ID(is_erase_background); - SANE_OPTION_ID(background_color_range); - SANE_OPTION_ID(sharpen); - SANE_OPTION_ID(erase_morr); - SANE_OPTION_ID(erase_grids); // 除网纹 - SANE_OPTION_ID(error_extend); - SANE_OPTION_ID(is_noise_modify); - SANE_OPTION_ID(noise_threshold); - SANE_OPTION_ID(paper); - SANE_OPTION_ID(is_custom_area); - SANE_OPTION_ID(curstom_area_l); - SANE_OPTION_ID(curstom_area_r); - SANE_OPTION_ID(curstom_area_t); - SANE_OPTION_ID(curstom_area_b); - SANE_OPTION_ID(is_size_check); - SANE_OPTION_ID(page); - SANE_OPTION_ID(blank_page_threshold); // 跳过空白页灵敏度 - SANE_OPTION_ID(resolution); - SANE_OPTION_ID(image_quality); - SANE_OPTION_ID(is_swap); // 交换正反面 - SANE_OPTION_ID(is_split); // 图像拆分 - SANE_OPTION_ID(is_auto_deskew); // 自动纠偏 - SANE_OPTION_ID(is_custom_gamma); - SANE_OPTION_ID(bright); - SANE_OPTION_ID(contrast); - SANE_OPTION_ID(gamma); - SANE_OPTION_ID(is_erase_black_frame); // bool - SANE_OPTION_ID(deep_sample); - SANE_OPTION_ID(threshold); - SANE_OPTION_ID(anti_noise); // 抗噪等级 - SANE_OPTION_ID(margin); - SANE_OPTION_ID(fill_background); - SANE_OPTION_ID(is_anti_permeate); - SANE_OPTION_ID(anti_permeate_level); - SANE_OPTION_ID(is_erase_hole); - SANE_OPTION_ID(search_hole_range); - SANE_OPTION_ID(is_filling_color); // 色彩填充 - SANE_OPTION_ID(is_ultrasonic_check); - SANE_OPTION_ID(is_check_staple); - SANE_OPTION_ID(scan_mode); // 扫描张数 - SANE_OPTION_ID(scan_count); // 扫描数量 - SANE_OPTION_ID(text_direction); - SANE_OPTION_ID(is_rotate_bkg180); - SANE_OPTION_ID(is_check_dogear); - SANE_OPTION_ID(dogear_size); - SANE_OPTION_ID(is_check_skew); - SANE_OPTION_ID(skew_range); - SANE_OPTION_ID(black_white_threshold); // 二值化图像阈值 - SANE_OPTION_ID(is_photo_mode); // 照片模式 - SANE_OPTION_ID(double_feed_handle); // 双张图片处理 - SANE_OPTION_ID(scan_when_paper_on); // 待纸扫描 - SANE_OPTION_ID(feed_strength); // 分纸强度 - SANE_OPTION_ID(power_scheme); // 休眠时间 - SANE_OPTION_ID(is_auto_strength); // 自动搓纸强度 - SANE_OPTION_ID(feed_strength_value); // 自动搓纸强度设定值 - SANE_OPTION_ID(is_reverse_bw); // 黑白图像反色输出 - SANE_OPTION_ID(is_erase_hole_l); // 穿孔移除 - 左 - SANE_OPTION_ID(search_hole_range_l); // 穿孔搜索范围 - 左 - SANE_OPTION_ID(is_erase_hole_r); // 穿孔移除 - 右 - SANE_OPTION_ID(search_hole_range_r); // 穿孔搜索范围 - 右 - SANE_OPTION_ID(is_erase_hole_t); // 穿孔移除 - 上 - SANE_OPTION_ID(search_hole_range_t); // 穿孔搜索范围 - 上 - SANE_OPTION_ID(is_erase_hole_b); // 穿孔移除 - 下 - SANE_OPTION_ID(search_hole_range_b); // 穿孔搜索范围 - 下 - SANE_OPTION_ID(fold_direction); // 对折模式 - - // SANE-ex option ID: - SANE_OPTION_ID(ex_multiout_type); // int - SANE_OPTION_ID(ex_auto_color_type); // int - SANE_OPTION_ID(ex_color_mode); // int - SANE_OPTION_ID(ex_sharpen); // int - SANE_OPTION_ID(ex_paper); // paper_value - SANE_OPTION_ID(ex_paper_lateral); // bool - SANE_OPTION_ID(ex_auto_paper_size); // bool - SANE_OPTION_ID(ex_is_paper_auto_crop); // bool - SANE_OPTION_ID(ex_text_direction); // float 90, 180, ..., -1 is auto-text-direction - SANE_OPTION_ID(ex_duplex); // bool - SANE_OPTION_ID(ex_fill_background); // bool true - 凸多边形 - SANE_OPTION_ID(ex_discard_blank_page); // bool - SANE_OPTION_ID(ex_discard_blank_receipt); // bool - SANE_OPTION_ID(ex_is_page_fold); // bool - SANE_OPTION_ID(ex_color_filter); // int (filter_value) - SANE_OPTION_ID(ex_color_enhance); // int (enhance_value) - SANE_OPTION_ID(ex_final_compression); // int - SANE_OPTION_ID(ex_final_format); // SANE_FinalImgFormat - SANE_OPTION_ID(ex_serial); // std::string - SANE_OPTION_ID(ex_to_be_scan); // bool - SANE_OPTION_ID(ex_scan_with_hole); // bool - SANE_OPTION_ID(ex_device_code); // std::string - SANE_OPTION_ID(ex_power); // int - SANE_OPTION_ID(ex_hardware_version); // std::string - SANE_OPTION_ID(ex_ip); // std::string - - // ui ... - COM_API_OVERRIDE(bool, ui_show_main(HWND parent)); - COM_API_OVERRIDE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true)); - COM_API_OVERRIDE(bool, ui_show_progress(HWND parent)); - COM_API_OVERRIDE(void, ui_hide(void)); - COM_API_OVERRIDE(bool, ui_is_ok(void)); - - // twain - COM_API_OVERRIDE(void, twain_set_transfer(twain_xfer xfer)); - COM_API_OVERRIDE(void, twain_set_compression(SANE_CompressionType compression, void* detail = NULL)); - COM_API_OVERRIDE(int, twain_get_config(char* buf, size_t* len)); - COM_API_OVERRIDE(int, twain_set_config(char* buf, size_t len)); - - // methods: -public: - int handle_device_event(int ev_code, void* data, unsigned int* len); -}; \ No newline at end of file diff --git a/sane/ui.cpp b/sane/ui.cpp deleted file mode 100644 index 7c9c779..0000000 --- a/sane/ui.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "pch.h" -#include "ui.h" - -#include "huagaotwain.h" // for sane_invoker::load_dll - - -twain_ui::twain_ui(const wchar_t* path) : path_(path), dll_(NULL) - , show_(NULL), hide_(NULL), event_(NULL), hui_(NULL) - , good_(false) -{ - good_ = load(); -} -twain_ui::~twain_ui() -{ - if (hui_ && hide_) - hide_(hui_); - - if (dll_) - FreeLibrary(dll_); -} - -bool twain_ui::load() -{ - std::wstring dll(path_ + L"\\huagaoui.dll"); - - sane_invoker::load_dll(dll.c_str(), &dll_); - if (!dll_) - return false; - - show_ = (ui_show_api)GetProcAddress(dll_, "ui_show"); - hide_ = (ui_hide_api)GetProcAddress(dll_, "ui_hide"); - event_ = (handle_event_api)GetProcAddress(dll_, "handle_event"); - - return show_ && hide_ && event_; -} - -void twain_ui::show_main_ui(LPSANEAPI api) -{ - type_ = UITYPE::UI_MAIN; - if (show_) - hui_ = show_(UITYPE::UI_MAIN, api); -} -void twain_ui::show_setting_ui(LPSANEAPI api, bool with_scan) -{ - if (show_) - { - type_ = with_scan ? UITYPE::UI_SETTING_AND_SCAN : UITYPE::UI_SETTING; - hui_ = show_(type_, api); - } -} -void twain_ui::show_progress_ui(LPSANEAPI api) -{ - type_ = UITYPE::UI_PROGRESS; - if (show_) - hui_ = show_(UITYPE::UI_PROGRESS, api); -} -void twain_ui::hide_ui(void) -{ - if (hui_ && hide_) - hide_(hui_); - hui_ = NULL; -} -void twain_ui::handle_sane_event(int sane_ev, void* data, unsigned int* len) -{ - if (event_) - event_((SANE_Event)sane_ev, data, len); -} - -bool twain_ui::is_ok(void) -{ - return good_; -} - -bool twain_ui::is_progress_ui_showing(void) -{ - return type_ == UITYPE::UI_PROGRESS; -} \ No newline at end of file diff --git a/sane/ui.h b/sane/ui.h deleted file mode 100644 index 3cd151a..0000000 --- a/sane/ui.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -#include -#include "huagao/huagao_ui.h" - - -class twain_ui -{ - HMODULE dll_; - ui_show_api show_; - ui_hide_api hide_; - handle_event_api event_; - ui_handle hui_; - std::wstring path_; - bool good_; - UITYPE type_; - - bool load(void); - -public: - twain_ui(const wchar_t* path); - ~twain_ui(); - -public: - void show_main_ui(LPSANEAPI api); - void show_setting_ui(LPSANEAPI api, bool with_scan); - void show_progress_ui(LPSANEAPI api); - void hide_ui(void); - void handle_sane_event(int sane_ev, void* data, unsigned int* len); - - bool is_ok(void); - bool is_progress_ui_showing(void); -}; diff --git a/sln/hgscanner.sln b/sln/hgscanner.sln index 9b65298..b2d57b4 100644 --- a/sln/hgscanner.sln +++ b/sln/hgscanner.sln @@ -4,10 +4,19 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 16.0.33214.272 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sane", "..\sane\sane.vcxproj", "{6EEC8A02-7F98-4422-8ED6-2434D43BD1E1}" + ProjectSection(ProjectDependencies) = postProject + {9ED4B425-73E0-423E-9712-455E777481B4} = {9ED4B425-73E0-423E-9712-455E777481B4} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scanner", "..\device\scanner.vcxproj", "{9ED4B425-73E0-423E-9712-455E777481B4}" + ProjectSection(ProjectDependencies) = postProject + {7776AB6D-6296-4F7A-A6ED-E9A4D6290DD9} = {7776AB6D-6296-4F7A-A6ED-E9A4D6290DD9} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "twain", "..\twain\twain.vcxproj", "{C3B47CE2-27CE-4509-AB59-3C0F194F0FCE}" + ProjectSection(ProjectDependencies) = postProject + {6EEC8A02-7F98-4422-8ED6-2434D43BD1E1} = {6EEC8A02-7F98-4422-8ED6-2434D43BD1E1} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "setup", "setup", "{F6774650-403F-476C-8373-2EA8D4AF06FF}" EndProject diff --git a/twain/load_sane.cpp b/twain/load_sane.cpp deleted file mode 100644 index 9660d61..0000000 --- a/twain/load_sane.cpp +++ /dev/null @@ -1,246 +0,0 @@ -#include "pch.h" -#include "load_sane.h" -#include -#include // for SHFileOperationW -#include "../../sdk/include/huagao/brand.h" - -#pragma comment(lib, "shell32.lib") - -namespace load_sane_util -{ - static std::wstring sane_path(L""); - static HMODULE sane_module(NULL); - static int (__stdcall* sane_inst)(SCANNERID, ISaneInvoker**) = NULL; - static int(__stdcall* is_on)(SCANNERID) = NULL; - static int(__stdcall* init)(void*) = NULL; - static int(__stdcall* uninit)(void*) = NULL; - static void(__stdcall* log)(const wchar_t*, int) = NULL; - - static std::string u2m(const wchar_t* u, int page) - { - char* ansi = NULL; - int len = 0; - std::string mb(""); - - len = WideCharToMultiByte(page, 0, u, lstrlenW(u), NULL, 0, NULL, NULL); - ansi = new char[len + 2]; - len = WideCharToMultiByte(page, 0, u, lstrlenW(u), ansi, len, NULL, NULL); - ansi[len--] = 0; - mb = ansi; - delete[] ansi; - - return mb; - } - static std::wstring m2u(const char* m, int page) - { - wchar_t* unic = NULL; - int len = 0; - std::wstring u(L""); - - len = MultiByteToWideChar(page, 0, m, lstrlenA(m), NULL, 0); - unic = new wchar_t[len + 2]; - len = MultiByteToWideChar(page, 0, m, lstrlenA(m), unic, len); - unic[len--] = 0; - u = unic; - delete[] unic; - - return u; - } - static std::wstring reg_read(HKEY root, const wchar_t* path, const wchar_t* name) - { - HKEY key = NULL; - - RegOpenKeyW(root, path, &key); - if (!key) - return L""; - - wchar_t* buf = NULL; - DWORD len = 0; - DWORD type = REG_SZ; - std::wstring ret(L""); - - RegQueryValueExW(key, name, NULL, &type, (LPBYTE)buf, &len); - if (len) - { - buf = new wchar_t[len + 4]; - memset(buf, 0, (len + 4) * sizeof(*buf)); - RegQueryValueExW(key, name, NULL, &type, (LPBYTE)buf, &len); - ret = buf; - delete[] buf; - } - RegCloseKey(key); - - return ret; - } - static std::wstring reg_get_app_installing_path(std::wstring* rp = NULL) - { - std::wstring path(m2u(PRODUCT_VENDOR, CP_ACP)), key(L"DriverPath"); - - path.insert(0, L"Software\\"); - path += L"Scan"; - - if (sizeof(void*) != 4) - key += L"64"; - - if (rp) - *rp = path + L"\\" + key; - - return reg_read(HKEY_LOCAL_MACHINE, path.c_str(), key.c_str()); - } - static int load_dll(const wchar_t* path_dll, HMODULE* dll) - { - HMODULE h = LoadLibraryW(path_dll); - int ret = GetLastError(); - wchar_t info[128] = { 0 }; - - swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret); - OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str()); - if (!h && (ret == ERROR_MOD_NOT_FOUND || ret == ERROR_BAD_EXE_FORMAT)) - { - std::wstring dir(path_dll); - size_t pos = dir.rfind(L'\\'); - wchar_t path[MAX_PATH] = { 0 }; - - GetDllDirectoryW(_countof(path) - 1, path); - if (pos != std::wstring::npos) - dir.erase(pos); - OutputDebugStringW((L"[TWAIN]Load: try change directory to " + dir + L"\r\n").c_str()); - SetDllDirectoryW(dir.c_str()); - h = LoadLibraryW(path_dll); - // h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - ret = GetLastError(); - swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret); - OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str()); - OutputDebugStringW((L"[TWAIN]Load: restore directory to " + std::wstring(path) + L"\r\n").c_str()); - SetDllDirectoryW(path); - } - - if (dll) - *dll = h; - - return ret; - } - - bool initialize(HMODULE me) - { - std::wstring reg_path(L""); - bool ret = false; - sane_path = reg_get_app_installing_path(®_path); - if (!sane_path.empty()) - { - sane_path += L"\\sane.dll"; - load_dll(sane_path.c_str(), &sane_module); - if (sane_module) - { - *((FARPROC*)&init) = GetProcAddress(sane_module, "initialize"); - *((FARPROC*)&sane_inst) = GetProcAddress(sane_module, "open_scanner"); - *((FARPROC*)&is_on) = GetProcAddress(sane_module, "is_scanner_online"); - *((FARPROC*)&uninit) = GetProcAddress(sane_module, "uninitialize"); - *((FARPROC*)&log) = GetProcAddress(sane_module, "log_info"); - ret = is_ok(); - if (ret) - ret = init(NULL) == 0; - } - } - - if (!ret) - MessageBoxW(NULL, (reg_path + L": " + sane_path).c_str(), L"Load scanner driver failed:", MB_OK); - - return ret; - } - bool is_ok(void) - { - wchar_t info[128] = { 0 }; - swprintf_s(info, _countof(info) - 1, L"[TWAIN]Load: sane_inst: %s, is_on: %s, init: %s, uninit: %s\r\n" - , sane_inst != NULL ? "ok" : "not found" - , is_on != NULL ? "ok" : "not found" - , init != NULL ? "ok" : "not found" - , uninit != NULL ? "ok" : "not found"); - - return sane_inst != NULL && is_on != NULL && init != NULL && uninit != NULL; - } - bool is_online(SCANNERID guid) - { - if (is_on) - return is_on(guid); - else - return false; - } - ISaneInvoker* open(SCANNERID guid, int* err) - { - ISaneInvoker* ret = NULL; - int code = 0; - - if (!err) - err = &code; - - if (sane_inst) - *err = sane_inst(guid, &ret); - - return ret; - } - void uninitialize(void) - { - sane_inst = NULL; - is_on = NULL; - init = NULL; - log = NULL; - - if (uninit) - uninit(NULL); - uninit = NULL; - - if (sane_module) - { - FreeLibrary(sane_module); - sane_module = NULL; - } - sane_path = L""; - sane_inst = NULL; - } - void log_info(const wchar_t* info, int level) - { - if (log) - log(info, level); - } - - std::string utf82ansi(const char* utf8) - { - return u2m(m2u(utf8, CP_UTF8).c_str(), CP_ACP); - } - std::string ansi2utf8(const char* ansi) - { - return u2m(m2u(ansi, CP_ACP).c_str(), CP_UTF8); - } - std::wstring ansi2unic(const char* ansi) - { - return m2u(ansi, CP_ACP); - } - - int move_file(const char* from, const char* to) - { - return move_file(ansi2unic(from).c_str(), ansi2unic(to).c_str()); - } - int move_file(const wchar_t* from, const wchar_t* to) - { - SHFILEOPSTRUCTW fo = { 0 }; - int ret = 0; - std::wstring _from(from), _to(to ? to : L""); - - if (wcsicmp(from, to) == 0) - return 0; - - _from += std::wstring((wchar_t*)&ret, 2); // ended with double '\0' - fo.pFrom = &_from[0]; - _to += std::wstring((wchar_t*)&ret, 2); // ended with double '\0' - fo.pTo = &_to[0]; - fo.fFlags = FOF_NO_UI | FOF_NO_CONNECTED_ELEMENTS; // 614 | 2000 - fo.wFunc = FO_MOVE; - - ret = SHFileOperationW(&fo); - if (ret == /*DE_SAMEFILE*/0x71) - ret = 0; - - return ret; - } -}; diff --git a/twain/load_sane.h b/twain/load_sane.h deleted file mode 100644 index 137fe29..0000000 --- a/twain/load_sane.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -// utility for loading sane component ... - -#include "../sane/s2t_api.h" -#include - -namespace load_sane_util -{ - bool initialize(HMODULE me); - bool is_ok(void); - bool is_online(SCANNERID guid); - ISaneInvoker* open(SCANNERID guid, int* err); - void uninitialize(void); - void log_info(const wchar_t* info, int level); - - std::string utf82ansi(const char* utf8); - std::string ansi2utf8(const char* ansi); - std::wstring ansi2unic(const char* ansi); - - int move_file(const char* from, const char* to); - int move_file(const wchar_t* from, const wchar_t* to); -}; - diff --git a/twain/twain.vcxproj b/twain/twain.vcxproj index 566b172..17c4b26 100644 --- a/twain/twain.vcxproj +++ b/twain/twain.vcxproj @@ -77,32 +77,36 @@ $(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath) $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ - $(LibraryPath) - huagaotwain400.ds + $(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) + huagaotwain200.ds + true - $(LibraryPath) - huagaotwain400.ds + $(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) + huagaotwain200.ds true $(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath) $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ + true false $(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath) $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ - $(LibraryPath) - huagaotwain400.ds + $(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) + huagaotwain100.ds + false - $(LibraryPath) + $(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\oem\huagao;$(LibraryPath) huagaotwain400.ds false $(SolutionDir)..\..\sdk\include\;$(SolutionDir)..\..\sdk\include\twain\;$(IncludePath) $(SolutionDir)..\..\release\win\$(PlatformTarget)\OEM\huagao\ $(SolutionDir)..\..\tmp\$(PlatformTarget)\huagao\$(Configuration)\$(ProjectName)\ + false @@ -119,16 +123,14 @@ Console true $(ProjectDir)twain.def - - + advapi32.lib - copy "$(TargetPath)" C:\Windows\twain_32\HuagoTwain\$(TargetName) /y -move /Y "$(TargetPath)" "$(OutputPath)$(TargetName)" -mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" -move /Y "$(OutputPath)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" -move /Y "$(OutputPath)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" -move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" + move /Y "$(TargetDir)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetPath)" "$(TargetDir)$(TargetName)" +copy /y "$(TargetDir)$(TargetName)" "C:\Windows\twain_32\HuaGoTwain" @@ -147,16 +149,14 @@ move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(Platf Console true $(ProjectDir)twain.def - - + advapi32.lib - copy "$(TargetPath)" C:\Windows\twain_64\HuagoTwain\$(TargetName) /y -move /Y "$(TargetPath)" "$(OutputPath)$(TargetName)" -mkdir "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" -move /Y "$(OutputPath)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" -move /Y "$(OutputPath)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" -move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" + move /Y "$(TargetDir)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetPath)" "$(TargetDir)$(TargetName)" +copy /y "$(TargetDir)$(TargetName)" "C:\Windows\twain_64\HuaGoTwain" @@ -177,12 +177,13 @@ move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(Platf true true $(ProjectDir)twain.def - - + advapi32.lib - - + move /Y "$(TargetDir)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetPath)" "$(TargetDir)$(TargetName)" @@ -204,16 +205,26 @@ move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(Platf true true $(ProjectDir)twain.def - - + advapi32.lib - - + move /Y "$(TargetDir)$(TargetName).lib" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetDir)$(TargetName).exp" "$(ProjectDir)..\..\sdk\lib\win\$(PlatformTarget)\OEM\huagao" +move /Y "$(TargetPath)" "$(TargetDir)$(TargetName)" + + + + + + + + + @@ -254,27 +265,54 @@ move /Y "$(OutputPath)$(TargetName).pdb" "$(ProjectDir)..\..\sdk\lib\win\$(Platf - - + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + + + NotUsing + NotUsing + NotUsing + NotUsing + - Create Create Create Create - - NotUsing - NotUsing - NotUsing - NotUsing - diff --git a/twain/twain.vcxproj.filters b/twain/twain.vcxproj.filters index 9f05408..993bede 100644 --- a/twain/twain.vcxproj.filters +++ b/twain/twain.vcxproj.filters @@ -5,37 +5,49 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms - - {668e9513-f6db-4f9d-9e0e-76cb8b5b7882} - - - {df21031b-938a-4a08-ae64-e869e2586201} - {89716198-13ed-4593-819e-97f4426c7baa} {6d97172d-832d-4c93-ad0e-92fdf76af26b} + + {d0f46d55-47e2-4b28-98e4-37435c417da3} + + + {ccf8d5b8-eea9-4223-87d3-6edea662380f} + + + {904bc294-9f58-4953-85d2-8cbd009a978f} + - - twain - Sources Sources - - Sources + + imports + + + imports + + + imports + + + imports + + + imports + + + imports - - twain - Headers @@ -48,128 +60,152 @@ Headers - - Headers - Headers - - twain\twpp + + imports - - twain\twpp + + imports - - twain\twpp + + imports - - twain\twpp + + imports - - twain\twpp + + imports - - twain\twpp + + imports - - twain\twpp + + imports - - twain\twpp + + Headers\twain - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp - - - twain\twpp + + Headers\twain - twain + Headers\twain + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp + + + Headers\twain\twpp diff --git a/twain/twain/huagaods.cpp b/twain/twain/huagaods.cpp deleted file mode 100644 index b7634e4..0000000 --- a/twain/twain/huagaods.cpp +++ /dev/null @@ -1,3556 +0,0 @@ -#ifdef max -#undef max -#endif -#ifdef min -#undef min -#endif - -#include -#include "huagaods.hpp" -//#include "twpp/twglue.hpp" -#include -#include -#if defined(WIN32) || defined(_WIN64) -#include -#include -#include -#define mktemp _mktemp -#endif // WIN32 - -using namespace std; - -#define enum2str(R) #R - -#pragma warning(disable: 4700) - -using namespace Twpp; -using namespace std::placeholders; - -extern HMODULE me_; - -// WIA COM: IStiUSD & IWiaMiniDrv - -//custom define caps enum -enum CapTypeEx : unsigned short { - CAP_TYPE_EX_FILL_BLACK_BKG = 0x8004, - CAP_TYPE_EX_ROTATE_BKG_180 = 0x8005, - CAP_TYPE_EX_SCREW_DETECT = 0x8006, - CAP_TYPE_EX_ENHANCE_COLOR = 0x8007, - CAP_TYPE_EX_DARK_SAMPLE = 0x8016, - CAP_TYPE_EX_FILL_HOLE = 0x8018, - CAP_TYPE_EX_SCREW_DETECT_LEVEL = 0x8021, - CAP_TYPE_EX_SHARPEN = 0x8022, - CAP_TYPE_EX_HARDWARE_VERSION = 0x8025, - CAP_TYPE_EX_RID_RED = 0x8026, - CAP_TYPE_EX_FOLD = 0x8037, - CAP_TYPE_EX_STAPLE_DETECT = 0x8090, - CAP_TYPE_EX_DISCARD_BLANK_RECEIPT = 0x8091, - CAP_TYPE_EX_FILL_HOLE_RATIO = 0x8092, - CAP_TYPE_EX_FLIP = 0x8094, // switch front back - CAP_TYPE_EX_RID_RED_HSV = 0x8095, - CAP_TYPE_EX_DOGEAR_DETECT = 0x8096, - CAP_TYPE_EX_BKG_FILLING_METHOD = 0x8097, - CAP_TYPE_EX_EDGE_IDENT = 0x8098, - CAP_TYPE_EX_ANTI_NOISE = 0x8099, - CAP_TYPE_EX_THRESHOLD = 0x8100, - CAP_TYPE_EX_DETACH_NOISE = 0x8101, - CAP_TYPE_EX_DETACH_NOISE_THRESHOLD = 0x8102, - CAP_TYPE_EX_SIZE_DETECT = 0x8103, - CAP_TYPE_EX_POWER_LEVEL = 0x8104, - CAP_TYPE_EX_ENCODE = 0x8105, - CAP_TYPE_EX_CROP_MODEL = 0x8106, - CAP_TYPE_EX_DOGEAR_DIST = 0x8107, - CAP_TYPE_EX_IMAGE_SPLIT = 0x8108, - CAP_TYPE_EX_FADE_BKG = 0x8109, - CAP_TYPE_EX_FADE_BKG_VALUE = 0x8110, - CAP_TYPE_EX_TO_BE_SCAN = 0x8111, - CAP_TYPE_EX_MULTI_OUT = 0x8112, - CAP_TYPE_EX_MULTI_OUT_TYPE = 0x8113, - CAP_TYPE_EX_SCAN_WITH_HOLE = 0x8114, - CAP_TYPE_EX_IP = 0x8200, - - // SANE豸ԭʼ͸ - CAP_EX_SANE = (int)CapType::CustomBase + 0x800, - CAP_EX_SANE_is_multiout, - CAP_EX_SANE_multiout_type, - CAP_EX_SANE_color_mode, - CAP_EX_SANE_erase_color, - CAP_EX_SANE_erase_multiout_red, - CAP_EX_SANE_erase_paper_red, - CAP_EX_SANE_is_erase_background, - CAP_EX_SANE_background_color_range, - CAP_EX_SANE_sharpen, - CAP_EX_SANE_erase_morr, - CAP_EX_SANE_erase_grids, - CAP_EX_SANE_error_extend, - CAP_EX_SANE_is_noise_modify, - CAP_EX_SANE_noise_threshold, - CAP_EX_SANE_paper, - CAP_EX_SANE_is_custom_area, - CAP_EX_SANE_curstom_area_l, - CAP_EX_SANE_curstom_area_r, - CAP_EX_SANE_curstom_area_t, - CAP_EX_SANE_curstom_area_b, - CAP_EX_SANE_is_size_check, - CAP_EX_SANE_page, - CAP_EX_SANE_blank_page_threshold, - CAP_EX_SANE_resolution, - CAP_EX_SANE_image_quality, - CAP_EX_SANE_is_swap, - CAP_EX_SANE_is_split, - CAP_EX_SANE_is_auto_deskew, - CAP_EX_SANE_is_custom_gamma, - CAP_EX_SANE_bright, - CAP_EX_SANE_contrast, - CAP_EX_SANE_gamma, - CAP_EX_SANE_is_erase_black_frame, - CAP_EX_SANE_deep_sample, - CAP_EX_SANE_threshold, - CAP_EX_SANE_anti_noise, - CAP_EX_SANE_margin, - CAP_EX_SANE_fill_background, - CAP_EX_SANE_is_anti_permeate, - CAP_EX_SANE_anti_permeate_level, - CAP_EX_SANE_is_erase_hole, - CAP_EX_SANE_search_hole_range, - CAP_EX_SANE_is_filling_color, - CAP_EX_SANE_is_ultrasonic_check, - CAP_EX_SANE_is_check_staple, - CAP_EX_SANE_scan_mode, - CAP_EX_SANE_scan_count, - CAP_EX_SANE_text_direction, - CAP_EX_SANE_is_rotate_bkg180, - CAP_EX_SANE_is_check_dogear, - CAP_EX_SANE_dogear_size, - CAP_EX_SANE_is_check_skew, - CAP_EX_SANE_skew_range, - CAP_EX_SANE_black_white_threshold, - CAP_EX_SANE_is_photo_mode, - CAP_EX_SANE_double_feed_handle, - CAP_EX_SANE_scan_when_paper_on, - CAP_EX_SANE_feed_strength, - CAP_EX_SANE_power_scheme, - CAP_EX_SANE_is_auto_strength, - CAP_EX_SANE_feed_strength_value, - CAP_EX_SANE_is_reverse_bw, - CAP_EX_SANE_is_erase_hole_l, - CAP_EX_SANE_search_hole_range_l, - CAP_EX_SANE_is_erase_hole_r, - CAP_EX_SANE_search_hole_range_r, - CAP_EX_SANE_is_erase_hole_t, - CAP_EX_SANE_search_hole_range_t, - CAP_EX_SANE_is_erase_hole_b, - CAP_EX_SANE_search_hole_range_b, - CAP_EX_SANE_fold_direction, - //CAP_EX_SANE_fold_type, - CAP_EX_SANE_color_correction, // 2023-02-24 15:31:19 ɫƫУ // 2023-02-24 15:28:46 ģʽ - // END for SANE豸ԭʼ͸ - ///////////////////////////////////////////////////////////////////////// -}; -enum // .twain/first.cfg: [twain-app] flow=0 -{ - TWAIN_APP_TRANSFER_NORMAL = 0, // first get head and then bits - TWAIN_APP_TRANSFER_REVERSE, // first get bits and then head -}; - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// entry ... -TWPP_ENTRY(huagao_ds) - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// utilites ... -// some helper functions to handle capability stuff -#define RETURN_ENUM_DESC(en, v, space) \ - if(v == space::en) \ - return L###en; - -const wchar_t* desc_state(DsState s, wchar_t unk[20]) -{ - RETURN_ENUM_DESC(Closed, s, DsState); - RETURN_ENUM_DESC(Open, s, DsState); - RETURN_ENUM_DESC(Enabled, s, DsState); - RETURN_ENUM_DESC(XferReady, s, DsState); - RETURN_ENUM_DESC(Xferring, s, DsState); - - swprintf(unk, L"%d", s); - - return unk; -} -const wchar_t* desc_data_group(DataGroup d, wchar_t unk[20]) -{ - RETURN_ENUM_DESC(Control, d, DataGroup); - RETURN_ENUM_DESC(Image, d, DataGroup); - RETURN_ENUM_DESC(Audio, d, DataGroup); - - { - swprintf(unk, L"%d", d); - - return unk; - } -} -const wchar_t* desc_data(Dat d, wchar_t unk[20]) -{ - RETURN_ENUM_DESC(Null, d, Dat); - RETURN_ENUM_DESC(Capability, d, Dat); - RETURN_ENUM_DESC(Event, d, Dat); - RETURN_ENUM_DESC(Identity, d, Dat); - RETURN_ENUM_DESC(Parent, d, Dat); - RETURN_ENUM_DESC(PendingXfers, d, Dat); - RETURN_ENUM_DESC(SetupMemXfer, d, Dat); - RETURN_ENUM_DESC(SetupFileXfer, d, Dat); - RETURN_ENUM_DESC(Status, d, Dat); - RETURN_ENUM_DESC(UserInterface, d, Dat); - RETURN_ENUM_DESC(XferGroup, d, Dat); - RETURN_ENUM_DESC(CustomData, d, Dat); - RETURN_ENUM_DESC(DeviceEvent, d, Dat); - RETURN_ENUM_DESC(FileSystem, d, Dat); - RETURN_ENUM_DESC(PassThrough, d, Dat); - RETURN_ENUM_DESC(Callback, d, Dat); - RETURN_ENUM_DESC(StatusUtf8, d, Dat); - RETURN_ENUM_DESC(Callback2, d, Dat); - RETURN_ENUM_DESC(ImageInfo, d, Dat); - RETURN_ENUM_DESC(ImageLayout, d, Dat); - RETURN_ENUM_DESC(ImageMemXfer, d, Dat); - RETURN_ENUM_DESC(ImageNativeXfer, d, Dat); - RETURN_ENUM_DESC(ImageFileXfer, d, Dat); - RETURN_ENUM_DESC(CieColor, d, Dat); - RETURN_ENUM_DESC(GrayResponse, d, Dat); - RETURN_ENUM_DESC(RgbResponse, d, Dat); - RETURN_ENUM_DESC(JpegCompression, d, Dat); - RETURN_ENUM_DESC(Palette8, d, Dat); - RETURN_ENUM_DESC(ExtImageInfo, d, Dat); - RETURN_ENUM_DESC(Filter, d, Dat); - RETURN_ENUM_DESC(AudioFileXfer, d, Dat); - RETURN_ENUM_DESC(AudioInfo, d, Dat); - RETURN_ENUM_DESC(AudioNativeXfer, d, Dat); - RETURN_ENUM_DESC(IccProfile, d, Dat); - RETURN_ENUM_DESC(ImageMemFileXfer, d, Dat); - RETURN_ENUM_DESC(EntryPoint, d, Dat); - - { - swprintf(unk, L"%d", d); - - return unk; - } -} -const wchar_t* desc_msg(Msg m, wchar_t unk[20]) -{ - RETURN_ENUM_DESC(Null, m, Msg); - RETURN_ENUM_DESC(Get, m, Msg); - RETURN_ENUM_DESC(GetCurrent, m, Msg); - RETURN_ENUM_DESC(GetDefault, m, Msg); - RETURN_ENUM_DESC(GetFirst, m, Msg); - RETURN_ENUM_DESC(GetNext, m, Msg); - RETURN_ENUM_DESC(Set, m, Msg); - RETURN_ENUM_DESC(Reset, m, Msg); - RETURN_ENUM_DESC(QuerySupport, m, Msg); - RETURN_ENUM_DESC(GetHelp, m, Msg); - RETURN_ENUM_DESC(GetLabel, m, Msg); - RETURN_ENUM_DESC(GetLabelEnum, m, Msg); - RETURN_ENUM_DESC(SetConstraint, m, Msg); - RETURN_ENUM_DESC(XferReady, m, Msg); - RETURN_ENUM_DESC(CloseDsReq, m, Msg); - RETURN_ENUM_DESC(CloseDsOk, m, Msg); - RETURN_ENUM_DESC(DeviceEvent, m, Msg); - RETURN_ENUM_DESC(OpenDsm, m, Msg); - RETURN_ENUM_DESC(CloseDsm, m, Msg); - RETURN_ENUM_DESC(OpenDs, m, Msg); - RETURN_ENUM_DESC(CloseDs, m, Msg); - RETURN_ENUM_DESC(UserSelect, m, Msg); - RETURN_ENUM_DESC(DisableDs, m, Msg); - RETURN_ENUM_DESC(EnableDs, m, Msg); - RETURN_ENUM_DESC(EnableDsUiOnly, m, Msg); - RETURN_ENUM_DESC(ProcessEvent, m, Msg); - RETURN_ENUM_DESC(EndXfer, m, Msg); - RETURN_ENUM_DESC(StopFeeder, m, Msg); - RETURN_ENUM_DESC(ChangeDir, m, Msg); - RETURN_ENUM_DESC(CreateDir, m, Msg); - RETURN_ENUM_DESC(Delete, m, Msg); - RETURN_ENUM_DESC(FormatMedia, m, Msg); - RETURN_ENUM_DESC(GetClose, m, Msg); - RETURN_ENUM_DESC(GetFirstFile, m, Msg); - RETURN_ENUM_DESC(GetInfo, m, Msg); - RETURN_ENUM_DESC(GetNextFile, m, Msg); - RETURN_ENUM_DESC(Rename, m, Msg); - RETURN_ENUM_DESC(Copy, m, Msg); - RETURN_ENUM_DESC(AutomaticCaptureDir, m, Msg); - RETURN_ENUM_DESC(PassThrough, m, Msg); - RETURN_ENUM_DESC(RegisterCallback, m, Msg); - RETURN_ENUM_DESC(ResetAll, m, Msg); - RETURN_ENUM_DESC(CustomBase, m, Msg); - - - { - swprintf(unk, L"%d", m); - - return unk; - } -} -const wchar_t* desc_return_code(ReturnCode rc, wchar_t unk[20]) -{ - RETURN_ENUM_DESC(Success, rc, ReturnCode); - RETURN_ENUM_DESC(Failure, rc, ReturnCode); - RETURN_ENUM_DESC(CheckStatus, rc, ReturnCode); - RETURN_ENUM_DESC(Cancel, rc, ReturnCode); - RETURN_ENUM_DESC(DsEvent, rc, ReturnCode); - RETURN_ENUM_DESC(NotDsEvent, rc, ReturnCode); - RETURN_ENUM_DESC(XferDone, rc, ReturnCode); - RETURN_ENUM_DESC(EndOfList, rc, ReturnCode); - RETURN_ENUM_DESC(InfoNotSupported, rc, ReturnCode); - RETURN_ENUM_DESC(DataNotAvailable, rc, ReturnCode); - RETURN_ENUM_DESC(Busy, rc, ReturnCode); - RETURN_ENUM_DESC(ScannerLocked, rc, ReturnCode); - - { - swprintf(unk, L"%d", rc); - - return unk; - } -} -const wchar_t* desc_condition_code(ConditionCode c, wchar_t unk[20]) -{ - RETURN_ENUM_DESC(Success, c, ConditionCode); - RETURN_ENUM_DESC(Bummer, c, ConditionCode); - RETURN_ENUM_DESC(LowMemory, c, ConditionCode); - RETURN_ENUM_DESC(NoDs, c, ConditionCode); - RETURN_ENUM_DESC(MaxConnections, c, ConditionCode); - RETURN_ENUM_DESC(OperationError, c, ConditionCode); - RETURN_ENUM_DESC(BadCap, c, ConditionCode); - RETURN_ENUM_DESC(BadProtocol, c, ConditionCode); - RETURN_ENUM_DESC(BadValue, c, ConditionCode); - RETURN_ENUM_DESC(SeqError, c, ConditionCode); - RETURN_ENUM_DESC(BadDest, c, ConditionCode); - RETURN_ENUM_DESC(CapUnsupported, c, ConditionCode); - RETURN_ENUM_DESC(CapBadOperation, c, ConditionCode); - RETURN_ENUM_DESC(CapSeqError, c, ConditionCode); - RETURN_ENUM_DESC(Denied, c, ConditionCode); - RETURN_ENUM_DESC(FileExists, c, ConditionCode); - RETURN_ENUM_DESC(FileNotFound, c, ConditionCode); - RETURN_ENUM_DESC(NotEmpty, c, ConditionCode); - RETURN_ENUM_DESC(PaperJam, c, ConditionCode); - RETURN_ENUM_DESC(PaperDoubleFeed, c, ConditionCode); - RETURN_ENUM_DESC(FileWriteError, c, ConditionCode); - RETURN_ENUM_DESC(CheckDeviceOnline, c, ConditionCode); - RETURN_ENUM_DESC(InterLock, c, ConditionCode); - RETURN_ENUM_DESC(DamagedCorner, c, ConditionCode); - RETURN_ENUM_DESC(FocusError, c, ConditionCode); - RETURN_ENUM_DESC(DocTooLight, c, ConditionCode); - RETURN_ENUM_DESC(DocTooDark, c, ConditionCode); - RETURN_ENUM_DESC(NoMedia, c, ConditionCode); - - { - swprintf(unk, L"%d", c); - - return unk; - } -} - -template -static Result oneValGet(Msg msg, Capability& data, const T& value) { - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - case Msg::GetDefault: - data = Capability::createOneValue(data.type(), value); - return {}; - - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -static Result oneValGetString(Msg msg, Capability& data, std::string value) { - Str255 str; - str.setData(value.c_str(), value.size()); - return oneValGet(msg, data, str); -} - -template -static Result enmGet(Msg msg, Capability& data, const T& value) { - switch (msg) { - case Msg::Get: - data = Capability::createEnumeration(data.type(), { value }); - return {}; - case Msg::GetCurrent: - case Msg::GetDefault: - data = Capability::createOneValue(data.type(), value); - return {}; - - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -template -static Result oneValGetSet(Msg msg, Capability& data, T& value, const T& def) { - switch (msg) { - case Msg::Reset: - value = def; - // fallthrough - case Msg::Get: - case Msg::GetCurrent: - data = Capability::createOneValue(data.type(), value); - return {}; - - case Msg::GetDefault: - data = Capability::createOneValue(data.type(), def); - return {}; - - case Msg::Set: - value = data.currentItem(); - return {}; - - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -template -static Result oneValGetSetConst(Msg msg, Capability& data, const T& def) { - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - case Msg::GetDefault: - case Msg::Reset: - data = Capability::createOneValue(data.type(), def); - return {}; - - case Msg::Set: - return data.currentItem() == def ? - Result() : Result(ReturnCode::Failure, ConditionCode::BadValue); - - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -template -static Result enmGetSetConst(Msg msg, Capability& data, const T& def) { - switch (msg) { - case Msg::Get: - data = Capability::createEnumeration(data.type(), { def }); - return {}; - - case Msg::GetCurrent: - case Msg::GetDefault: - case Msg::Reset: - data = Capability::createOneValue(data.type(), def); - return {}; - - case Msg::Set: - return data.currentItem() == def ? - Result() : Result(ReturnCode::Failure, ConditionCode::BadValue); - - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -template -Result CapSupGetAllReset(Msg msg, Capability& data, std::initializer_list values, T1& currvalue, T2 defaultvalue, UInt32 currindex, UInt32 defaultindex) { - switch (msg) { - case Msg::Get: - data = Capability::createEnumeration(values, currindex, defaultindex); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::GetCurrent: - data = Capability::createOneValue((T2)currvalue); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - currvalue = (T1)defaultvalue; - data = Capability::createOneValue(defaultvalue); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} -template -Result CapSupGetAllReset(Msg msg, Capability& data, std::list values, T1& currvalue, T2 defaultvalue, UInt32 currindex, UInt32 defaultindex) { - switch (msg) { - case Msg::Get: - data = Capability::createEnumeration(values, currindex, defaultindex); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::GetCurrent: - data = Capability::createOneValue((T2)currvalue); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - currvalue = (T1)defaultvalue; - data = Capability::createOneValue(defaultvalue); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} -template -Result CapSupGetAllResetEx(Msg msg, Capability& data, std::initializer_list values, T1& currvalue, T2 defaultvalue, UInt32 currindex, UInt32 defaultindex) { - switch (msg) { - case Msg::Get: - data = Capability::createEnumeration(cap, values, currindex, defaultindex); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::GetCurrent: - data = Capability::createOneValue(cap, (T2)currvalue); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - currvalue = (T1)defaultvalue; - data = Capability::createOneValue(cap, defaultvalue); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} -template -Result CapSupGetAllResetEx(Msg msg, Capability& data, std::list values, T1& currvalue, T2 defaultvalue, UInt32 currindex, UInt32 defaultindex) { - switch (msg) { - case Msg::Get: - data = Capability::createEnumeration(cap, values, currindex, defaultindex); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::GetCurrent: - data = Capability::createOneValue(cap, (T2)currvalue); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - currvalue = (T1)defaultvalue; - data = Capability::createOneValue(cap, defaultvalue); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -template -Result CapSupGetAllReset(Msg msg, Capability& data, T1& currvalue, T2 defaultvalue) { - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - data = Capability::createOneValue((T2)currvalue); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - currvalue = (T1)defaultvalue; - data = Capability::createOneValue(defaultvalue); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} -template -Result CapSupGetAllResetEx(Msg msg, Capability& data, T1& currvalue, T2 defaultvalue) { - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - data = Capability::createOneValue(cap, (T2)currvalue); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - currvalue = (T1)defaultvalue; - data = Capability::createOneValue(cap, defaultvalue); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -template -Result cap_get_enum_values(Msg msg, Capability& data, std::list values, T& cur, T& def, UInt32 cur_ind, UInt32 def_ind) -{ - switch (msg) - { - case Msg::Get: - data = Capability::createEnumeration(cap, values.size(), cur_ind, def_ind); - //data = Capability::createArray(cap, values.size()); - { - auto arr = data.enumeration(); - int i = 0; - for (const auto& v : values) - arr[i++] = v; - } - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::GetCurrent: - data = Capability::createOneValue(cap, cur); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - data = Capability::createOneValue(cap, def); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} -template -Result cap_get_one_value(Msg msg, Capability& data, T& cur, T& def, T* lower, T* upper, T* step) -{ - switch (msg) - { - case Msg::Get: - if (lower && upper && step) - { - data = Capability::createRange(cap, *lower, *upper, *step, cur, def); - return { ReturnCode::Success, ConditionCode::Success }; - } - case Msg::GetCurrent: - data = Capability::createOneValue(cap, cur); - return { ReturnCode::Success, ConditionCode::Success }; - case Msg::Reset: - case Msg::GetDefault: - data = Capability::createOneValue(cap, def); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -template -Result CapSupGetAll(Msg msg, Capability& data, T1& currvalue, T2 defaultvalue) { - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - case Msg::GetDefault: - data = Capability::createOneValue((T2)defaultvalue); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} -template -Result CapSupGetAllEx(Msg msg, Capability& data, T1& currvalue, T2 defaultvalue) { - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - case Msg::GetDefault: - data = Capability::createOneValue(defaultvalue); - return { ReturnCode::Success, ConditionCode::Success }; - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } -} - -static void copy_type(Bool& to, bool from) -{ - to = from; -} -static void copy_type(bool& to, Bool from) -{ - to = (bool)from; -} -static void copy_type(BYTE& to, bool from) -{ - to = from; -} -static void copy_type(bool& to, BYTE from) -{ - to = (bool)from; -} -static void copy_type(UInt32& to, int from) -{ - to = from; -} -static void copy_type(int& to, UInt32 from) -{ - to = from; -} -static void copy_type(Fix32& to, double from) -{ - to = (float)from; -} -static void copy_type(Fix32& to, float from) -{ - to = from; -} -static void copy_type(float& to, Fix32 from) -{ - to = from.toFloat(); -} -static void copy_type(Str255& to, std::string from) -{ - to.setData(load_sane_util::utf82ansi(from.c_str()).c_str()); -} -static void copy_type(std::string& to, Str255 from) -{ - to = load_sane_util::ansi2utf8(from.data()); -} -static void copy_type(Str64& to, std::string from) -{ - to.setData(load_sane_util::utf82ansi(from.c_str()).c_str()); -} -static void copy_type(std::string& to, Str64 from) -{ - to = load_sane_util::ansi2utf8(from.data()); -} - -template -bool list_value_at(std::list& lst, int ind, T& t) -{ - bool found = false; - - if (ind >= 0) - { - typename std::list::iterator it = lst.begin(); - for (; it != lst.end(); ++it, --ind) - { - if (ind == 0) - { - t = *it; - found = true; - break; - } - } - } - - return found; -} -template -int distance(std::vector& vec, const T& v, int offset = sane_opts::RANGE_POS_ENUM_BEGIN) -{ - return std::distance(vec.begin() + offset, - std::find(vec.begin() + offset, vec.end(), v)); -} - -UINT16 bit_depth_from_sane(int sane) -{ - if (sane == COLOR_BW) - return 1; - else if (sane == COLOR_GRAY) - return 8; - else if (sane == COLOR_RGB) - return 24; - else - return /*sane*/24; -} -static ImageFileFormat from_sane_image_type(int sane_img_type) -{ - ImageFileFormat fmt = ImageFileFormat::Bmp; - switch (sane_img_type) - { - case SANE_IMAGE_TYPE_PNG: - fmt = ImageFileFormat::Png; - break; - case SANE_IMAGE_TYPE_JPG: - fmt = ImageFileFormat::Jpx; - break; - case SANE_IMAGE_TYPE_TIFF: - fmt = ImageFileFormat::Tiff; - break; - case SANE_IMAGE_TYPE_JFIF: - fmt = ImageFileFormat::Jfif; - break; - case SANE_IMAGE_TYPE_WEBP: - break; - case SANE_IMAGE_TYPE_PDF: - fmt = ImageFileFormat::Pdf; - break; - case SANE_IMAGE_TYPE_GIF: - break; - case SANE_IMAGE_TYPE_SVG: - break; - default: - break; - } - - return fmt; -} - -struct -{ - Filter twain; - int sane; -}g_filter[] = { {Filter::Red, FILTER_RED}, {Filter::Green, FILTER_GREEN}, {Filter::Blue, FILTER_BLUE}, {Filter::None, FILTER_NONE} }; -Filter from_sane_filter(int sane) -{ - for (int i = 0; i < _countof(g_filter); ++i) - { - if (g_filter[i].sane == sane) - return g_filter[i].twain; - } - - return Filter::None; -} -int to_sane_filter(Filter twain) -{ - for (int i = 0; i < _countof(g_filter); ++i) - { - if (g_filter[i].twain == twain) - return g_filter[i].sane; - } - - return FILTER_NONE; -} - -struct -{ - Filter twain; - int sane; -}g_enhance[] = { {Filter::Red, ENHANCE_RED}, {Filter::Green, ENHANCE_GREEN}, {Filter::Blue, ENHANCE_BLUE}, {Filter::None, ENHANCE_NONE} }; -Filter from_sane_enhance(int sane) -{ - for (int i = 0; i < _countof(g_filter); ++i) - { - if (g_filter[i].sane == sane) - return g_filter[i].twain; - } - - return Filter::None; -} -int to_sane_enhance(Filter twain) -{ - for (int i = 0; i < _countof(g_filter); ++i) - { - if (g_filter[i].twain == twain) - return g_filter[i].sane; - } - - return FILTER_NONE; -} - -float trans_range(float val, float min_from, float max_from, float min_to, float max_to, bool for_step = false) -{ - // transfer val in range [min_from, max_from] to value in range [min_to, max_to] - if (for_step) - { - val /= max_from - min_from; - val *= max_to - min_to; - } - else - { - val -= min_from; - val /= max_from - min_from; - val *= max_to - min_to; - val += min_to; - } - - return val; -} - -static void log_attr_access(int attr, int method) -{ - wchar_t msg[128] = { 0 }; - const wchar_t* op = L"Unknown Oper"; - -#define METHOD_DESC(oper) \ - if (method == (int)Msg::oper) \ - op = L###oper; - - METHOD_DESC(Set) - else METHOD_DESC(Reset) - else METHOD_DESC(Get) - else METHOD_DESC(GetCurrent) - else METHOD_DESC(GetDefault) - - swprintf_s(msg, _countof(msg) - 1, L"%s %04x\r\n", op, attr); - load_sane_util::log_info(msg, 0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// huagao_ds ... -#include "../../../sdk/include/huagao/brand.h" - -static Identity* srcIdent = new Identity( - Version(VERSION_MAIN, VERSION_SUB, Language::English, Country::China, VERSION_STR(VERSION_MAIN, VERSION_SUB, VERSION_BUILD1, VERSION_PATCH)), - DataGroup::Image, PRODUCT_VENDOR, PRODUCT_FAMILY, PRODUCT_NAME); -static const SCANNERID scanner_guid = MAKE_SCANNER_ID(PRODUCT_PID, PRODUCT_VID); - - -static std::once_flag oc; -huagao_ds::huagao_ds() : cur_head_(NULL), dpi_(200), xfer_ready_failed_(false), log_all_triple_(false), scanner_status_(SCANNER_STATUS_NOT_INIT),count_(-1) -{ - //std::call_once(oc, [&]() { log4cplus::Initializer(); }); -} -huagao_ds::~huagao_ds() -{ - if (memoryinfo.get()) { - m_memoryfalg = false; - if (memoryinfo->joinable()) - memoryinfo->join(); - } - if (cur_head_) - delete cur_head_; -} - -std::string huagao_ds::get_hidedlg_path(void) -{ - char szIniFile[MAX_PATH] = { 0 }; - SHGetSpecialFolderPathA(NULL, szIniFile, CSIDL_WINDOWS, TRUE); -#ifdef MAKEHUAGAO - strcat(szIniFile, "\\twain_32\\HuaGoScan\\hidedlg.exe"); -#elif defined AUGE - strcat(szIniFile, "\\twain_32\\AuGeScan\\hidedlg.exe"); -#elif defined HANVON - strcat(szIniFile, "\\twain_32\\HanvonScan\\hidedlg.exe"); -#elif defined LANXUM - strcat(szIniFile, "\\twain_32\\LANXUMSCAN\\hidedlg.exe"); -#else // MAKEHUAGAO - strcat(szIniFile, "\\twain_32\\ZhibenScan\\hidedlg.exe"); -#endif - - return szIniFile; -} -void huagao_ds::showmsg(const char* msg, int err) -{ - ShellExecuteA(NULL, "open", huagao_ds::get_hidedlg_path().c_str(), msg, NULL, SW_HIDE); -} -int __stdcall huagao_ds::on_scanner_event(int ev, void* param) -{ - return ((huagao_ds*)param)->handle_scanner_event(ev, false); -} - -const Identity& huagao_ds::defaultIdentity() noexcept { - // remember, we return a reference, therefore the identity must not be placed on the stack of this method - return *srcIdent; -} -Result huagao_ds::selectIdentity(Twpp::Identity& ident) noexcept { - // remember, we return a reference, therefore the identity must not be placed on the stack of this method - ident = *srcIdent; - - return success(); - - return { ReturnCode::Failure, ConditionCode::NoDs }; -} -Twpp::ConditionCode huagao_ds::condition_code_from_hg_error(int hgerr) -{ - if (hgerr == SCANNER_ERR_OK) - return Twpp::ConditionCode::Success; - if (hgerr == SCANNER_ERR_DEVICE_NOT_FOUND) - return Twpp::ConditionCode::CheckDeviceOnline; - if (hgerr == SCANNER_ERR_IO) - return Twpp::ConditionCode::OperationError; - if(hgerr == SCANNER_ERR_OUT_OF_RANGE) - return Twpp::ConditionCode::BadCap; - if(hgerr == SCANNER_ERR_DEVICE_NOT_SUPPORT) - return Twpp::ConditionCode::BadProtocol; - if(hgerr == SCANNER_ERR_INVALID_PARAMETER) - return Twpp::ConditionCode::BadValue; - if(hgerr == SCANNER_ERR_ACCESS_DENIED) - return Twpp::ConditionCode::Denied; - if(hgerr == SCANNER_ERR_OPEN_FILE_FAILED) - return Twpp::ConditionCode::FileNotFound; - if (hgerr == SCANNER_ERR_DEVICE_PAPER_JAMMED) - return Twpp::ConditionCode::PaperJam; - if (hgerr == SCANNER_ERR_DEVICE_DOUBLE_FEEDING) - return Twpp::ConditionCode::PaperDoubleFeed; - if (hgerr == SCANNER_ERR_WRITE_FILE_FAILED) - return Twpp::ConditionCode::FileWriteError; - if (hgerr == SCANNER_ERR_DEVICE_DOGEAR) - return Twpp::ConditionCode::DamagedCorner; - if (hgerr == SCANNER_ERR_DEVICE_NO_PAPER) - return Twpp::ConditionCode::NoMedia; - if (hgerr == SCANNER_ERR_OPENED_BY_OTHER_PROCESS) - return Twpp::ConditionCode::MaxConnections; - if(hgerr == SCANNER_ERR_INSUFFICIENT_MEMORY) - return Twpp::ConditionCode::LowMemory; - if(hgerr == SCANNER_ERR_DEVICE_NOT_FOUND) - return Twpp::ConditionCode::NoDs; - - return ConditionCode::Bummer; - - // return (Twpp::ConditionCode)((int)Twpp::ConditionCode::CustomBase + hgerr); -} - -Result huagao_ds::capabilityGet(const Identity& origin, Capability& data) -{ - return capCommon(origin, Msg::Get, data); -} -Result huagao_ds::capabilityGetCurrent(const Identity& origin, Capability& data) -{ - return capCommon(origin, Msg::GetCurrent, data); -} -Result huagao_ds::capabilityGetDefault(const Identity& origin, Capability& data) -{ - return capCommon(origin, Msg::GetDefault, data); -} -Result huagao_ds::capabilityQuerySupport(const Identity&, Capability& data) -{ - auto it = m_query.find(data.type()); - MsgSupport sup = it != m_query.end() ? it->second : msgSupportEmpty; - data = Capability::createOneValue(data.type(), sup); - return success(); -} -Result huagao_ds::capabilityReset(const Identity& origin, Capability& data) -{ - return capCommon(origin, Msg::Reset, data); -} -Result huagao_ds::capabilityResetAll(const Identity& origin) -{ - for (auto& pair : m_query) { - if ((pair.second & MsgSupport::Reset) != msgSupportEmpty) { - Capability dummyCap(pair.first); - capCommon(origin, Msg::Reset, dummyCap); - } - } - - return success(); -} -Result huagao_ds::capabilitySet(const Identity& origin, Capability& data) -{ - return capCommon(origin, Msg::Set, data); -} -Result huagao_ds::eventProcess(const Identity&, Event& event) -{ - const MSG* msg = (const MSG*)event.event(); - if (scanner_.get()) - { - int ev = scanner_->get_event(); - - if(ev) - handle_scanner_event(ev); - } - // event.setMessage(Msg::Null); - - - return { ReturnCode::NotDsEvent, ConditionCode::Success }; -} -Twpp::Result huagao_ds::deviceEventGet(const Twpp::Identity& origin, Twpp::DeviceEvent& data) -{ - // data = DeviceEvent::simple(load_sane_util::take_event(), "HUAGAO"); - // return success(); - - return seqError(); -} -Result huagao_ds::identityOpenDs(const Identity& id) -{ - //singleton_ = CreateMutexA(NULL, FALSE, "LookitApp"); - //if (GetLastError() == ERROR_ALREADY_EXISTS) { //ѾͬMutexõ. - // CloseHandle(singleton_); - // singleton_ = NULL; - // showmsg("ʾ", 202); - // - // return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - //} - if (!load_sane_util::is_ok()) - load_sane_util::initialize(me_); - if (!load_sane_util::is_ok()) - { - CloseHandle(singleton_); - singleton_ = NULL; - return bummer(); - } - - Identity target(id); - Result result = huagao_ds::selectIdentity(target); - if (scanner_.get()) - scanner_.reset(); - - if (result.returnCode() != ReturnCode::Success) - { - CloseHandle(singleton_); - singleton_ = NULL; - load_sane_util::uninitialize(); - return result; - } - - int err = 0; - Sleep(100); - scanner_.reset(load_sane_util::open(scanner_guid, &err)); - if (!scanner_.get()) - { - //CloseHandle(singleton_); - //singleton_ = NULL; - - load_sane_util::uninitialize(); - return { ReturnCode::Failure, huagao_ds::condition_code_from_hg_error(err) }; - } - // ui_.reset(new twain_ui(local_utility::reg_get_app_installing_path().c_str())); - scanner_->set_event_callback(&huagao_ds::on_scanner_event, this); - if (get_config_number(L"twain-app", L"flow") == TWAIN_APP_TRANSFER_REVERSE) - { - cur_head_ = new SANE_Parameters; - memset(cur_head_, 0, sizeof(SANE_Parameters)); - } - log_all_triple_ = get_config_number(L"twain-app", L"log-all-triple") == 1; - - m_compression = Compression::None; - init_support_caps(); - m_fileXfer.setFormat(ImageFileFormat::Bmp); - scanner_status_ = SCANNER_STATUS_READY; - - return success(); -} -Result huagao_ds::identityCloseDs(const Identity&) -{ - // ui_.reset(); - if (scanner_.get()) - { - scanner_->set_event_callback(); - scanner_.reset(); - } - if (singleton_) - { - CloseHandle(singleton_); - singleton_ = NULL; - } - load_sane_util::uninitialize(); - scanner_status_ = SCANNER_STATUS_NOT_INIT; - - return success(); -} -Result huagao_ds::pendingXfersGet(const Identity&, PendingXfers& data) -{ - if (!scanner_.get()) - return seqError(); - - data.setCount(get_scanned_image_count(-1)); - return success(); -} -Result huagao_ds::pendingXfersEnd(const Identity& id, PendingXfers& data) -{ - return pendingXfersGet(id, data); -} -Result huagao_ds::pendingXfersReset(const Identity&, PendingXfers& data) -{ - pending_xfer_.clear(); - data.setCount(get_scanned_image_count(-1)); - - return success(); -} -Result huagao_ds::setupMemXferGet(const Identity& id, SetupMemXfer& data) -{ - SANE_Parameters head; - size_t total = 0; - DWORD to = cur_head_ ? -1 : 0; - - if (!scanner_.get() || get_scanned_image_count(to) == 0) - { - if (cur_head_) - { - UserInterface ui(FALSE, FALSE, (Twpp::Handle)0); - data.setPreferredSize(1); - call(id, DataGroup::Control, Dat::UserInterface, Msg::DisableDs, &ui); - } - else - { - int def_w = 2000, - def_h = 6000; - data.setMinSize(def_w * 3 * def_h); - data.setPreferredSize(def_w * 3 * def_h); - data.setMaxSize(def_w * 3 * def_h); - } - return success(); - } - - if (scanner_->get_first_image_header(&head, &total)) - { - if (m_compression == Compression::None) - { - int line_bytes = (head.bytes_per_line + 3) / 4 * 4; - data.setMinSize(head.bytes_per_line); - data.setPreferredSize(line_bytes * head.lines); - data.setMaxSize(line_bytes * head.lines); - } - else - { - data.setMinSize(total); - data.setPreferredSize(total); - data.setMaxSize(total); - } - - return success(); - } - else - return badValue(); -} -Result huagao_ds::userInterfaceDisable(const Identity&, UserInterface& ui) -{ - if (scanner_.get()) - scanner_->stop(); - - return success(); -} -Result huagao_ds::userInterfaceEnable(const Identity&, UserInterface& ui) -{ - if (!ui.showUi()) - { - if (m_bIndicator && !scanner_->ui_show_progress((HWND)ui.parent().raw())) - return seqError(); - - xfer_ready_failed_ = false; - scanner_->twain_set_transfer((twain_xfer)m_capXferMech); - scanner_status_ = SCANNER_STATUS_SCAN_1; - app_trigger_event_ = false; - int err = scanner_->start(); - if (err == SCANNER_ERR_OK) - { - return success(); - } - else - { - scanner_status_ = SCANNER_STATUS_READY; - // if (err == SCANNER_ERR_DEVICE_NO_PAPER) - return { ReturnCode::Failure, huagao_ds::condition_code_from_hg_error(err) }; - - return bummer(); - } - } - - return showTwainUI(ui); -} -Result huagao_ds::userInterfaceEnableUiOnly(const Identity&, UserInterface& ui) -{ - // as a minimal source, we do not support GUI that just saves settings - return showTwainUI(ui, true); -} -Twpp::Result huagao_ds::extImageInfoGet(const Identity& origin, ExtImageInfo& data) -{ - for (int i = 0; i < data.size(); ++i) - { - InfoId id = data.at(i).id(); - Twpp::Info& info = data.at(i); - - if (id == InfoId::BarCodeCount) - { - info.allocSimple(Type::UInt32); - *info.items()[0].data() = 0; - } - else if (id == InfoId::BarCodeType) - { - info.allocSimple(Type::UInt32); - *info.items()[0].data() = BarCodeType::ThreeOfNine; - } - else if(id == InfoId::BarCodeTextLength) - { - info.allocSimple(Type::UInt32); - *info.items()[0].data() = 0; - } - else if (id == InfoId::BarCodeText) - { - //info.allocSimple(Type::Str255, 1); - //info.items()[0].data()->setData(std::to_string(6922868285266 + i).c_str()); - } - else - info.setReturnCode(ReturnCode::InfoNotSupported); - } - - return success(); - - return { ReturnCode::Failure, ConditionCode::NoMedia }; -} -Result huagao_ds::imageInfoGet(const Identity&, ImageInfo& data) -{ - SANE_Parameters head; - bool ok = false; - int res = 200; - - if (!scanner_.get()) - return seqError(); - if (cur_head_ && cur_head_->lines) - { - memcpy(&head, cur_head_, sizeof(head)); - ok = true; - cur_head_->lines = 0; - res = dpi_; - } - else - { - if (!scanner_->wait_image()) - { - // notifyCloseOk(); - return success(); // ÷Ҫسɹ - } - ok = scanner_->get_first_image_header(&head, NULL, &res); - if(ok) - dpi_ = res; - } - - if (ok) - { - if (head.format == SANE_FRAME_RGB) - { - data.setBitsPerPixel(head.depth * 3); - data.setSamplesPerPixel(3); - data.bitsPerSample()[0] = data.bitsPerSample()[1] = data.bitsPerSample()[2] = head.depth; - } - else - { - data.setSamplesPerPixel(1); - data.setBitsPerPixel(head.depth); - data.bitsPerSample()[0] = head.depth; - } - data.setHeight(head.lines); - if (m_compression == Compression::Group4) - data.setPixelType(PixelType::BlackWhite); - else - { - if (head.format == SANE_FRAME_RGB) - data.setPixelType(PixelType::Rgb); - else if(head.format == SANE_FRAME_GRAY) - data.setPixelType(head.depth == 1 ? PixelType::BlackWhite : PixelType::Gray); - } - data.setPlanar(false); - data.setWidth(head.pixels_per_line); - - data.setXResolution((float)res); - data.setYResolution((float)res); - data.compression(m_compression); - } - else - { - load_sane_util::log_info(L" imageInfoGet is false\r\n", 0); - } - wchar_t buf[128]; - std::wstring f(L"imageInfoGet:"); - int h = data.height(); - int w = data.width(); - int bitsPerPixel = data.bitsPerPixel(); - Compression compression = data.compression(); - PixelType pixelType = data.pixelType(); - bool planar = data.planar(); - Fix32 xr = data.xResolution(); - swprintf_s(buf, _countof(buf) - 1,L"imageInfoGet: h-->%d w-->%d bitsPerPixel-->%d compression-->%d pixelType-->%d planar-->%d\r\n", h, w, bitsPerPixel, compression, pixelType, planar); - load_sane_util::log_info(buf, 0); - return success(); -} -Result huagao_ds::imageLayoutGet(const Identity&, ImageLayout& data) -{ - SANE_Parameters head = { 0 }; - - if (!scanner_.get()) - return seqError(); - else if(get_scanned_image_count(-1) == 0) - return { ReturnCode::Failure, condition_code_from_hg_error(scanner_->last_error()) }; - - int res = 200; - - scanner_->get_first_image_header(&head, NULL, &res); - data.setDocumentNumber(1); - data.setFrameNumber(1); - data.setPageNumber(1); - data.setFrame(Frame(0, 0, static_cast(head.pixels_per_line) / res, static_cast(head.lines) / res)); - - return success(); -} -Result huagao_ds::imageLayoutGetDefault(const Identity& origin, ImageLayout& data) -{ - return imageLayoutGet(origin, data); -} -Result huagao_ds::imageLayoutSet(const Identity& origin, ImageLayout& lay) -{ - // we dont support setting image frame - - ImageLayout def; - imageLayoutGetDefault(origin, def); - - return lay.frame() == def.frame() ? success() : badValue(); -} -Result huagao_ds::imageLayoutReset(const Identity& origin, ImageLayout& data) -{ - return imageLayoutGet(origin, data); -} -Result huagao_ds::imageMemXferGet(const Identity& origin, ImageMemXfer& data) -{ - if (!scanner_.get()) - return seqError(); - - if (get_scanned_image_count(-1) == 0 && !pending_xfer_.img) - { - //if (!cur_head_ || !scanner_->wait_image()) - //{ - // notifyCloseOk(); - // return seqError(); - //} - - return { ReturnCode::Failure, condition_code_from_hg_error(scanner_->last_error()) }; - } - - IScanImg *img = pending_xfer_.img ? pending_xfer_.img : scanner_->take_first_image(TWAIN_XFER_Memory); - unsigned long long off = pending_xfer_.img ? pending_xfer_.off : 0; - unsigned char *dst = (unsigned char*)data.memory().data().data(); - UInt32 buf_l = data.memory().size(); - unsigned int line_l = img->line_bytes(), - rows = data.memory().size() / line_l; - size_t want_read = rows * line_l; - Result ret = { ReturnCode::XferDone, ConditionCode::Success }; - - if (rows == 0) - return badValue(); - - if (pending_xfer_.img) - { - img->add_ref(); - pending_xfer_.clear(); - } - else if(cur_head_) - { - img->copy_header(cur_head_); - } - data.setBytesPerRow(line_l); - data.setColumns(img->width()); - data.setRows(rows); - data.setXOffset(0); - data.setYOffset(UInt32(off / line_l)); - data.setCompression(m_compression); - if (m_compression != Compression::None) - { - want_read = img->bytes() - off; - if (buf_l < want_read) - { - want_read = buf_l; - } - img->read(dst, &want_read, off); - data.setBytesWritten(want_read); - off += want_read; - if (off < img->bytes()) - { - pending_xfer_.img = img; - pending_xfer_.off = (unsigned int)off; - img->add_ref(); - ret = success(); - } - } - else if (img->read(dst, &want_read, off) == SCANNER_ERR_OK) - { - want_read /= line_l; - data.setRows(want_read); - want_read *= line_l; - data.setBytesWritten(want_read); - off += want_read; - if (off < img->bytes()) - { - pending_xfer_.img = img; - pending_xfer_.off = (unsigned int)off; - img->add_ref(); - ret = success(); - } - } - else - { - ret = { ReturnCode::XferDone, ConditionCode::Bummer }; - } - img->release(); - - return ret; -} -Result huagao_ds::imageNativeXferGet(const Identity& id, ImageNativeXfer& data) -{ - if (!scanner_.get()) - return seqError(); - else if(get_scanned_image_count(-1) == 0) - return { ReturnCode::Failure, condition_code_from_hg_error(scanner_->last_error()) }; - - IScanImg* img = scanner_->take_first_image(TWAIN_XFER_Native); - - if (!img) - return seqError(); - if (data) - data.release(); - data = ImageNativeXfer(img->bytes()); - - unsigned long long off = 0; - unsigned int total = img->bytes(); - unsigned char* src = img->data(off, &total), - * dst = data.data().data(); - while (off < img->bytes() && src) - { - std::copy(src, src + total, dst); - dst += total; - off += total; - if (off >= img->bytes()) - break; - total = img->bytes() - (unsigned int)off; - src = img->data(off, &total); - } - img->release(); - - return { ReturnCode::XferDone, ConditionCode::Success }; -} -Twpp::Result huagao_ds::pendingXfersStopFeeder(const Identity& origin, PendingXfers& data) -{ - if (scanner_.get()) - scanner_->stop(); - - return success(); -} -Twpp::Result huagao_ds::imageFileXferGet(const Twpp::Identity& origin) -{ - // assume that the file format has set before start-scanning, so we write-down the image content to file directly here ... - if (!scanner_.get()) - return seqError(); - else if(get_scanned_image_count(-1) == 0) - return { ReturnCode::Failure, condition_code_from_hg_error(scanner_->last_error()) }; - - IScanImg* img = scanner_->take_first_image(TWAIN_XFER_File); - Twpp::Result ret = seqError(); - FILE* dst = NULL; - - if (img) - { - std::string file(img->file()); - int cv_e = 0, - status = img->image_status(); - if (file.empty()) - { - dst = fopen(m_fileXfer.filePath().string().c_str(), "wb"); - ret = { ReturnCode::Failure, ConditionCode::FileWriteError }; - if (dst) - { - unsigned long long off = 0; - unsigned int total = img->bytes(); - unsigned char* src = img->data(off, &total); - while (src) - { - if (fwrite(src, 1, total, dst) != total) - break; - off += total; - if (off >= img->bytes()) - { - ret = Result(ReturnCode::XferDone, ConditionCode::Success); - break; - } - total = img->bytes() - (unsigned int)off; - src = img->data(off, &total); - } - - fclose(dst); - } - else - { - std::wstring f(L"CreateFile(" + load_sane_util::ansi2unic(m_fileXfer.filePath().string().c_str())); - wchar_t msg[128] = { 0 }; - - swprintf_s(msg, _countof(msg) - 1, L") = %d\r\n", GetLastError()); - f += msg; - load_sane_util::log_info(f.c_str(), 0); - } - img->release(); - } - else - { - load_sane_util::log_info((L"Map file to " + load_sane_util::ansi2unic(m_fileXfer.filePath().string().c_str()) + L"\r\n").c_str(), 0); - - img->keep_file(true); - img->release(); - cv_e = load_sane_util::move_file(file.c_str(), m_fileXfer.filePath().string().c_str()); - if (cv_e == 0) - ret = Result(ReturnCode::XferDone, ConditionCode::Success); - else - DeleteFileA(file.c_str()); - } - - if (ret.status() == ConditionCode::Success && m_fileXfer.format() != ImageFileFormat::Bmp) - { - SANE_ImageFormatConvert conv; - std::string target(m_fileXfer.filePath().string().c_str()); - - memset(&conv, 0, sizeof(conv)); - file = target + ".src"; - conv.src.fmt.img_format = SANE_IMAGE_TYPE_BMP; - conv.src.is_file = SANE_TRUE; - conv.src.data = file.c_str(); - conv.src.data_len = file.length(); - - conv.dst.fmt.img_format = (SANE_ImageType)m_fileXfer.format(); - conv.dst.fmt.compress.compression = (SANE_CompressionType)m_compression; - conv.dst.fmt.compress.detail = (void*)0; - conv.dst.fmt.detail = (void*)m_jpegQuality; - conv.dst.is_file = SANE_TRUE; - conv.dst.data = target.c_str(); - conv.dst.data_len = target.length(); - while (!MoveFileA(target.c_str(), file.c_str())) - { - if (cv_e == 0) - { - std::wstring info(L"[convert image format] Move '"); - wchar_t buf[80] = { 0 }; - - swprintf_s(buf, _countof(buf) - 1, L"%d\r\n", GetLastError()); - info += load_sane_util::ansi2unic(target.c_str()) + L"' to '" + load_sane_util::ansi2unic(file.c_str()) + L"' failed: "; - load_sane_util::log_info((info + buf).c_str(), 0); - } - if (++cv_e >= 9) - break; - Sleep(30); - } - if (cv_e < 9) - { - cv_e = scanner_->convert_image(&conv); - if (cv_e != SCANNER_ERR_OK) - ret = { ReturnCode::Failure, ConditionCode::OperationError }; - DeleteFileA(file.c_str()); - } - } - - //if (ret.status() == ConditionCode::Success) - //{ - // switch (status) - // { - // case SANE_Image_Statu_Blank: - // break; - // case SANE_Image_Statu_Double: - // ret.setStatus(ConditionCode::PaperDoubleFeed); - // break; - // case SANE_Image_Statu_Jammed: - // ret.setStatus(ConditionCode::PaperJam); - // break; - // } - //} - - { - std::wstring info(load_sane_util::ansi2unic(m_fileXfer.filePath().string().c_str())); - wchar_t r[80] = { 0 }; - swprintf_s(r, _countof(r) - 1, L": status = %d(Fail: 0x%x)\r\n", (int)ret.status(), cv_e); - load_sane_util::log_info((info + r).c_str(), 0); - } - } - - return ret; -} -Twpp::Result huagao_ds::setupFileXferGet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) -{ - data.setFilePath(m_fileXfer.filePath()); - data.setFormat(m_fileXfer.format()); - return success(); -} -Twpp::Result huagao_ds::setupFileXferGetDefault(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) -{ - Str255 str("HGTwain.bmp"); - data.setFilePath(str); - data.setFormat(ImageFileFormat::Bmp); - return success(); -} -Twpp::Result huagao_ds::setupFileXferSet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) -{ - m_fileXfer.setFilePath(data.filePath()); - m_fileXfer.setFormat(data.format()); - return success(); -} -Twpp::Result huagao_ds::setupFileXferReset(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) -{ - m_fileXfer.setFormat(Twpp::ImageFileFormat::Bmp); - std::string templateName = "HG"; - char* tempPath = mktemp((char*)templateName.c_str()); - if (tempPath) { - Str255 str; - str.setData(tempPath, strlen(tempPath)); - m_fileXfer.setFilePath(str); - return success(); - } - - return badProtocol(); -} -Result huagao_ds::call(const Identity& origin, DataGroup dg, Dat dat, Msg msg, void* data) { - try { - // we can override almost anything from SourceFromThis, even the top-most source instance call - //FileTools::write_log("D:\\1.txt", "call:datagroup-"+to_string((int)dg)+"dat-"+to_string(int(dat))+"msg-"+to_string(int(msg))); - Result rt; - - trigger_ProcessEvent(dg, dat, msg); // some APPs may be not trigger (Control, Event, ProcessEvent), we help them :( ... // ľɨ˲״̬ı䣬ֱȡͼ˴һ״̬ 2022-11-07 - - rt = Base::call(origin, dg, dat, msg, data); - if(log_all_triple_ || (int)rt.returnCode()) - { - wchar_t buf[128] = { 0 }, dgs[20] = { 0 }, dts[20] = { 0 }, ms[20] = { 0 }, ss[20] = { 0 }, rcs[20] = { 0 }, cs[20] = { 0 }; - swprintf_s(buf, _countof(buf) - 1, L"[%x - %s]DSEntry(%s, %s, %s) = {%s, %s}\r\n", GetCurrentThreadId(), desc_state(state(), ss), - desc_data_group(dg, dgs), desc_data(dat, dts), desc_msg(msg, ms), desc_return_code(rt, rcs), desc_condition_code((ConditionCode)(Status)rt, cs)); - load_sane_util::log_info(buf, 0); - } - return rt; - } - catch (const CapabilityException& e) { - //FileTools::writelog(log_ERROR, e.what()); - UNREFERENCED_PARAMETER(e); - return badValue(); - } -} -Result huagao_ds::customDataGet(const Twpp::Identity& origin, Twpp::CustomData& data) -{ - // get user setting from local file ... - if (!scanner_.get()) - return seqError(); - - char * buf = NULL; - size_t len = 0; - if (scanner_->twain_get_config(buf, &len) == SCANNER_ERR_INSUFFICIENT_MEMORY) - { - data = CustomData(len); - buf = data.lock(); - scanner_->twain_get_config(buf, &len); - } - - return success(); -} -Result huagao_ds::customDataSet(const Twpp::Identity& origin, Twpp::CustomData& data) -{ - // write user setting to local file ... - if (!scanner_.get()) - return seqError(); - - char* buf = data.lock(); - scanner_->twain_set_config(buf, data.size()); - - return success(); -} - -void huagao_ds::CapabilityPrintf(Twpp::Msg msg, std::string capability, std::string value) -{ - -} -Result huagao_ds::capCommon(const Identity&, Msg msg, Capability& data) { - auto it = m_caps.find(data.type()); - if (it != m_caps.end()) { - return (it->second)(msg, data); - } - - return capUnsupported(); -} -Twpp::Result huagao_ds::showTwainUI(Twpp::UserInterface& data, bool bUiOnly) -{ - // display user UI ... (setting UI, can we show my own main window here ?) - return scanner_->ui_show_setting((HWND)data.parent().raw(), !bUiOnly, m_bIndicator) ? success() : seqError(); -} -void huagao_ds::init_support_caps(void) -{ -#define SANE_ID(name) scanner_->sane_opt_id_##name##() - - m_query.clear(); - m_caps.clear(); - - //m_query[CapType::IExtImageInfo] = msgSupportGetAll; - //m_caps[CapType::IExtImageInfo] = std::bind(enmGet, _1, _2, Bool(true)); - - m_query[CapType::ISupportedExtImageInfo] = msgSupportGetAll; - m_caps[CapType::ISupportedExtImageInfo] = [this](Msg msg, Capability& data) { - data = Capability::createArray< CapType::ISupportedExtImageInfo>({ InfoId::BarCodeCount, InfoId::BarCodeText, InfoId::BarCodeType, InfoId::BarCodeTextLength }); - return success(); - }; - - m_query[CapType::SupportedCaps] = msgSupportGetAll; - m_caps[CapType::SupportedCaps] = [this](Msg msg, Capability& data) { - log_attr_access((int)CapType::SupportedCaps, (int)msg); - if ((msg == Msg::Get) || (Msg::GetCurrent == msg) || (Msg::GetDefault == msg)) { - data = Capability::createArray(m_caps.size()); - auto arr = data.array(); - std::vector all; - for (const auto& v : m_caps) - all.push_back((int)v.first); - std::sort(all.begin(), all.end()); - UInt32 i = 0; - for (const auto& kv : all) { - arr[i] = (CapType)kv; - i++; - } - return success(); - } - else - return capBadOperation(); - }; - - m_query[CapType::XferCount] = msgSupportGetAllSetReset; - m_caps[CapType::XferCount] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::XferCount, (int)msg); - if (msg == Msg::Set) { - auto item = data.currentItem(); - if (item > 65535 || item < -1 || item == 0) { - return badValue(); - } - int ret = SCANNER_ERR_OK; - int count = count_ = item; - - BYTE dup = 1; - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_duplex, NULL, &all); - dup = all[sane_opts::RANGE_POS_CURRENT]; - - if (dup && count >= 2) - { - count /= 2; - } - SET_SANE_OPT(ret, scanner_, scan_count, &count); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - std::vector count; - Int16 tmp_count = 0; - GET_SANE_OPT(int, scanner_, scan_count, NULL, &count); - tmp_count = count[sane_opts::RANGE_POS_CURRENT]; - - BYTE dup = 1; - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_duplex, NULL, &all); - dup = all[sane_opts::RANGE_POS_CURRENT]; - if (dup && tmp_count > 0 && tmp_count < 65535) - { - tmp_count *= 2; - } - - return oneValGetSet(msg, data, tmp_count, -1); - }; - - m_bIndicator = scanner_->ui_is_ok(); - if (m_bIndicator) - { - m_query[CapType::UiControllable] = msgSupportGetAll; - m_caps[CapType::UiControllable] = std::bind(oneValGet, _1, _2, Bool(true)); - - m_query[CapType::Indicators] = msgSupportGetAllSetReset; - m_caps[CapType::Indicators] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::Indicators, (int)msg); - if (Msg::Set == msg) { - auto show = data.currentItem(); - m_bIndicator = show; - load_sane_util::log_info(m_bIndicator ? L"Set show indicator: true\r\n" : L"Set show indicator: false\r\n", 0); - return success(); - } - load_sane_util::log_info(m_bIndicator ? L"Set show indicator: true\r\n" : L"Set show indicator: false\r\n", 0); - // data.type - if (!data.operator bool()) //з () Twain sample app ,data.m_cont is null,but DotNet data.m_cont not is null . - { - data = Capability::createEnumeration({ FALSE,TRUE }, m_bIndicator ? 1 : 0, 1); - } - else - data = Capability::createOneValue(m_bIndicator); - - return success(); - //return CapSupGetAllReset(msg, data, { TRUE,FALSE }, m_bIndicator, TRUE, (BOOL)(m_bIndicator ? 1 : 0), 1); - }; - } - - m_query[CapType::DeviceOnline] = msgSupportGetAll; - m_caps[CapType::DeviceOnline] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::DeviceOnline, (int)msg); - // CapabilityPrintf(msg, enum2str(CapType::DeviceOnline)); - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - case Msg::GetDefault: - if(scanner_.get()) - data = Capability::createOneValue((Twpp::Bool)scanner_->is_online()); - else - data = Capability::createOneValue((Twpp::Bool)(load_sane_util::is_online(scanner_guid))); - return success(); - - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } - }; - - m_query[CapType::ICompression] = msgSupportGetAllSetReset; - m_caps[CapType::ICompression] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::ICompression, (int)msg); - if (!scanner_.get()) - return seqError(); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (Compression::None == mech || mech == Compression::Group4) { - m_compression = mech; - scanner_->twain_set_compression((SANE_CompressionType)m_compression); - { - wchar_t info[128] = { 0 }; - swprintf_s(info, _countof(info) - 1, L"set CapType::ICompression = %s\r\n", Compression::None == mech ? L"None" : L"Group4"); - load_sane_util::log_info(info, 0); - } - return success(); - } - else - return badValue(); - } - return CapSupGetAllReset(msg, data, { Compression::None, Compression::Group4 }, m_compression, Compression::None, m_compression == Compression::None ? 0 : 1, 0); - }; - - m_query[CapType::IUnits] = msgSupportGetAllSetReset; - m_caps[CapType::IUnits] = std::bind(enmGetSetConst, _1, _2, Unit::Inches); - - m_query[CapType::IBitDepth] = msgSupportGetAllSetReset; - m_caps[CapType::IBitDepth] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::IBitDepth, (int)msg); - std::vector all; - int val = 0; - GET_SANE_OPT(int, scanner_, ex_color_mode, NULL, &all); - if (Msg::Set == msg || Msg::Reset == msg) { - int ret = SCANNER_ERR_INVALID_PARAMETER; - val = all[sane_opts::RANGE_POS_DEFAULT]; - if (Msg::Set == msg) - { - auto mech = data.currentItem(); - if (mech == 1) - val = COLOR_BW; - else if (mech == 8) - val = COLOR_GRAY; - else if (mech == 24) - val = COLOR_RGB; - else - val = mech; - } - { - wchar_t info[128] = { 0 }; - swprintf_s(info, _countof(info) - 1, L"set CapType::IBitDepth = %d\r\n", val); - load_sane_util::log_info(info, 0); - } - SET_SANE_OPT(ret, scanner_, ex_color_mode, &val); - if (Msg::Reset == msg) - { - UINT16 v = val; - data = Capability::createOneValue(CapType::IBitDepth, v); - } - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - UINT16 Now = bit_depth_from_sane(all[sane_opts::RANGE_POS_CURRENT]), Init = bit_depth_from_sane(all[sane_opts::RANGE_POS_DEFAULT]); - std::list vals; - UInt32 ni = distance(all, all[sane_opts::RANGE_POS_CURRENT]), - ii = distance(all, all[sane_opts::RANGE_POS_DEFAULT]); - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) - vals.push_back(bit_depth_from_sane(all[i])); - return cap_get_enum_values(msg, data, vals, Now, Init, ni, ii); - }; - - m_query[CapType::IBitOrder] = msgSupportGetAllSetReset; - m_caps[CapType::IBitOrder] = std::bind(oneValGetSetConst, _1, _2, BitOrder::MsbFirst); - - m_query[CapType::IPlanarChunky] = msgSupportGetAllSetReset; - m_caps[CapType::IPlanarChunky] = std::bind(enmGetSetConst, _1, _2, PlanarChunky::Chunky); - - m_query[CapType::IXResolution] = msgSupportGetAllSetReset; - m_caps[CapType::IXResolution] = /*m_caps[CapTypeEx::CAP_EX_SANE_resolution];*/ [this](Msg msg, Capability& data) { - log_attr_access((int)CapType::IXResolution, (int)msg); - if (!scanner_.get()) - return seqError(); - std::vector values; - value_limit limit = VAL_LIMIT_RANGE; - int init = 0, now = 0; - GET_SANE_OPT(int, scanner_, resolution, NULL, &values); - init = values[sane_opts::RANGE_POS_DEFAULT]; - now = values[sane_opts::RANGE_POS_CURRENT]; - switch (msg) { - case Msg::Get: - if (limit == VAL_LIMIT_RANGE) - { - data = Capability::createRange(Fix32((float)values[sane_opts::RANGE_POS_LOWER]) - , Fix32((float)values[sane_opts::RANGE_POS_UPPER]) - , Fix32((float)values[sane_opts::RANGE_POS_STEP]) - , Fix32((float)values[sane_opts::RANGE_POS_CURRENT]) - , Fix32((float)values[sane_opts::RANGE_POS_DEFAULT])); - return success(); - } - else if (limit == VAL_LIMIT_ENUM) - { - std::list vals; - Fix32 Now, Init; - UInt32 ni, ii; - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < values.size(); ++i) - { - Fix32 f; - float vf = (float)values[i]; - copy_type(f, vf); - vals.push_back(f); - } - float nowf = (float)now, initf = (float)init; - copy_type(Now, nowf); - copy_type(Init, initf); - ni = std::distance(vals.begin(), std::find(vals.begin(), vals.end(), Now)); - ii = std::distance(vals.begin(), std::find(vals.begin(), vals.end(), Init)); - return cap_get_enum_values(msg, data, vals, Now, Init, ni, ii); - } - case Msg::GetCurrent: - data = Capability::createOneValue(Fix32((float)now)); - return success(); - case Msg::GetDefault: - data = Capability::createOneValue(Fix32((float)init)); - return success(); - case Msg::Reset: - data = Capability::createOneValue(Fix32((float)init)); - case Msg::Set: { - auto mech = data.currentItem(); - int ret = SCANNER_ERR_OK; - float resl = (float)mech; - int resli = (int)resl; - SET_SANE_OPT(ret, scanner_, resolution, &resli); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - default: - return capBadOperation(); - } - }; - - m_query[CapType::IYResolution] = msgSupportGetAllSetReset; - m_caps[CapType::IYResolution] = /*m_caps[CapType::IXResolution];*/ [this](Msg msg, Capability& data) - { - Result ret = m_caps[CapType::IXResolution](msg, data); - - if (data.type() == CapType::IXResolution) - data.dangerous_set_cap(CapType::IYResolution); - - return ret; - }; - - m_query[CapType::IXNativeResolution] = msgSupportGetAll; - m_caps[CapType::IXNativeResolution] = std::bind(enmGet, _1, _2, Fix32(200.0)); - - m_query[CapType::IYNativeResolution] = msgSupportGetAll; - m_caps[CapType::IYNativeResolution] = m_caps[CapType::IXNativeResolution]; - - m_query[CapType::ISupportedSizes] = msgSupportGetAllSetReset; - m_caps[CapType::ISupportedSizes] = [this](Msg msg, Capability& data) { - log_attr_access((int)CapType::ISupportedSizes, (int)msg); - int now = 0, - init = 0; - std::vector all; - GET_SANE_OPT(int, scanner_, ex_paper, NULL, &all); - now = all[sane_opts::RANGE_POS_CURRENT]; - init = all[sane_opts::RANGE_POS_DEFAULT]; - if (msg == Msg::Set || msg == Msg::Reset) - { - if(msg == Msg::Set) - init = (int)data.currentItem(); - else - data = Capability::createOneValue((Twpp::PaperSize)init); - - SET_SANE_OPT(now, scanner_, ex_paper, &init); - return now == SCANNER_ERR_OK ? success() : badValue(); - } - - std::list vals; - Twpp::PaperSize Now = (PaperSize)now, - Init = (PaperSize)init; - UInt32 ni = distance(all, now), - ii = distance(all, init); - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) - vals.push_back((PaperSize)all[i]); - - return cap_get_enum_values(msg, data, vals, Now, Init, ni, ii); - }; - - m_query[CapType::IPhysicalWidth] = msgSupportGetAll; - m_caps[CapType::IPhysicalWidth] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::IPhysicalWidth, (int)msg); - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - case Msg::GetDefault: - { - float init = 10.0f; - int cur = 200; - SANE_Parameters param = { 0 }; - if (scanner_.get() && scanner_->get_first_image_header(¶m, NULL, &cur)) - init = param.bytes_per_line * 1.0f / cur; - data = Capability::createOneValue(data.type(), Fix32(init)); - return success(); - } - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } - }; - - m_query[CapType::IPhysicalHeight] = msgSupportGetAll; - m_caps[CapType::IPhysicalHeight] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::IPhysicalHeight, (int)msg); - switch (msg) { - case Msg::Get: - case Msg::GetCurrent: - case Msg::GetDefault: - { - float init = 10.0f; - int cur = 200; - SANE_Parameters param = { 0 }; - if (scanner_.get() && scanner_->get_first_image_header(¶m, NULL, &cur)) - init = param.lines * 1.0f / cur; - data = Capability::createOneValue(data.type(), Fix32(init)); - return success(); - } - default: - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } - }; - - m_query[CapType::IPixelFlavor] = msgSupportGetAllSetReset; - m_caps[CapType::IPixelFlavor] = std::bind(enmGetSetConst, _1, _2, PixelFlavor::Chocolate); - - m_query[CapType::IXferMech] = msgSupportGetAllSetReset; - m_caps[CapType::IXferMech] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::IXferMech, (int)msg); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if (mech == XferMech::Native || mech == XferMech::Memory || mech == XferMech::File) { - m_capXferMech = mech; - scanner_->twain_set_transfer((twain_xfer)m_capXferMech); - { - wchar_t info[128] = { 0 }, * des[] = {L"Native", L"File", L"Memory"}; - swprintf_s(info, _countof(info) - 1, L"set CapType::IXferMech = %s\r\n", des[(int)m_capXferMech]); - load_sane_util::log_info(info, 0); - } - return success(); - } - else { - return badValue(); - } - } - return CapSupGetAllReset(msg, data, { XferMech::Native, XferMech::File, XferMech::Memory }, m_capXferMech, XferMech::Native, (int)m_capXferMech, 0); - }; - - m_query[CapType::IPixelType] = msgSupportGetAllSetReset; - m_caps[CapType::IPixelType] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::IPixelType, (int)msg); - if (!scanner_.get()) - return seqError(); - std::vector values; - int init = 0, now = 0; - - GET_SANE_OPT(int, scanner_, ex_color_mode, NULL, &values); - now = values[sane_opts::RANGE_POS_CURRENT]; - init = values[sane_opts::RANGE_POS_DEFAULT]; - if (Msg::Reset == msg || Msg::Set == msg) - { - if(Msg::Set == msg) - init = (int)data.currentItem(); - { - wchar_t info[128] = { 0 }, * des[] = { L"BlackWhite", L"Gray", L"Rgb" }; - if((int)init < _countof(des)) - swprintf_s(info, _countof(info) - 1, L"set CapType::IPixelType = %s\r\n", des[(int)init]); - else - swprintf_s(info, _countof(info) - 1, L"set CapType::IPixelType = 0x%x\r\n", (int)init); - load_sane_util::log_info(info, 0); - } - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_color_mode, &init); - data = Capability::createOneValue((Twpp::PixelType)init); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - switch (msg) { - case Msg::Get: - if (1) - { - std::list vals; - UInt32 ni = distance(values, now), ii = distance(values, init); - Twpp::PixelType Init = (Twpp::PixelType)init, Now = (Twpp::PixelType)now; - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < values.size(); ++i) - vals.push_back((Twpp::PixelType)values[i]); - return cap_get_enum_values(msg, data, vals, Now, Init, ni, ii); - } - case Msg::GetCurrent: - data = Capability::createOneValue((Twpp::PixelType)now); - return success(); - case Msg::GetDefault: - data = Capability::createOneValue((Twpp::PixelType)init); - return success(); - } - return capBadOperation(); - }; - - m_query[CapType::IAutomaticColorEnabled] = msgSupportGetAllSetReset; - m_caps[CapType::IAutomaticColorEnabled] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IAutomaticColorEnabled, (int)msg); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - int ret = SCANNER_ERR_OK, val = mech ? COLOR_AUTO_MATCH : COLOR_RGB; - SET_SANE_OPT(ret, scanner_, ex_auto_color_type, &val); - - return success(); - } - std::vector all; - GET_SANE_OPT(int, scanner_, ex_auto_color_type, NULL, &all); - int twpt = all[sane_opts::RANGE_POS_CURRENT] == COLOR_AUTO_MATCH ? 1 : 0; - return CapSupGetAllReset(msg, data, { FALSE,TRUE }, twpt, false, twpt ? 1 : 0, 0); - }; - - m_query[CapType::IAutomaticColorNonColorPixelType] = msgSupportGetAllSetReset; - m_caps[CapType::IAutomaticColorNonColorPixelType] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IAutomaticColorNonColorPixelType, (int)msg); - if (msg == Msg::Set) { - int mech = (int)data.currentItem(); - { - if ((UInt16)mech == 0 || (UInt16)mech == 1) { - int ret = SCANNER_ERR_OK, - val = mech; - SET_SANE_OPT(ret, scanner_, ex_auto_color_type, &val); - if (ret == SCANNER_ERR_OK) - { - automaticcolortype_ = (UInt16)mech; - return success(); - } - } - } - return seqError(); - } - return CapSupGetAllReset(msg, data, { PixelType::BlackWhite, PixelType::Gray }, automaticcolortype_, PixelType::Gray, automaticcolortype_, 1); - }; - - m_query[CapType::IJpegQuality] = msgSupportGetAllSetReset; - m_caps[CapType::IJpegQuality] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IJpegQuality, (int)msg); - SANE_FinalImgFormat fif; - fif.img_format = SANE_IMAGE_TYPE_JPG; - if (Msg::Set == msg) { - auto mech = data.currentItem(); - if ((int)mech <= 0 || (int)mech > 100) - return badValue(); - - m_jpegQuality = (int)mech; - return success(); - //int ret = SCANNER_ERR_OK; - //fif.detail = (void*)mech; - //SET_SANE_OPT(ret, scanner_, ex_final_format, &fif); - //return ret == SCANNER_ERR_OK ? success() : badValue(); - } - //unsigned short q = 80; - //fif.detail = (void*)q; - //GET_SANE_OPT(SANE_FinalImgFormat, scanner_, ex_final_format, &fif, NULL, NULL, NULL); - //if(fif.img_format == SANE_IMAGE_TYPE_JPG) - // q = (unsigned short)fif.detail; - //return CapSupGetAllResetEx(msg, data, q, 80); - unsigned short q = m_jpegQuality; - return CapSupGetAllResetEx(msg, data, q, (UInt16)80); - }; - - m_query[CapType::IOrientation] = msgSupportGetAllSetReset; - m_caps[CapType::IOrientation] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::IOrientation, (int)msg); - CapabilityPrintf(msg, enum2str(CapTypeEx::IOrientation), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - bool lateral = mech == Orientation::Landscape; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_paper_lateral, &lateral); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - std::vector values; - GET_SANE_OPT(bool, scanner_, ex_paper_lateral, NULL, &values); - int lateral = values[sane_opts::RANGE_POS_CURRENT] ? (int)Orientation::Landscape : (int)Orientation::Portrait; - return CapSupGetAllReset(msg, data, { Orientation::Portrait, Orientation::Landscape }, lateral, Orientation::Portrait, lateral == 0 ? 0 : 1, 0); - }; - - m_query[CapType::IRotation] = msgSupportGetAllSetReset; - m_caps[CapType::IRotation] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::IRotation, (int)msg); - if (Msg::Set == msg) { - auto res = data.currentItem(); - float angle = res.toFloat(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_text_direction, &angle); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - std::vector values; - - GET_SANE_OPT(float, scanner_, ex_text_direction, NULL, &values); - - Fix32 Init = Fix32(values[sane_opts::RANGE_POS_DEFAULT]), Now = Fix32(values[sane_opts::RANGE_POS_CURRENT]); - std::list vls; - UInt32 i = distance(values, values[sane_opts::RANGE_POS_DEFAULT]), - n = distance(values, values[sane_opts::RANGE_POS_CURRENT]); - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < values.size(); ++i) - vls.push_back(Fix32(values[i])); - - return cap_get_enum_values(msg, data, vls, Now, Init, n, i); - }; - - m_query[CapType::EnableDsUiOnly] = msgSupportGetAll; - m_caps[CapType::EnableDsUiOnly] = std::bind(enmGet, _1, _2, Bool(true)); - - m_query[CapType::PaperDetectable] = msgSupportGetAll; - m_caps[CapType::PaperDetectable] = std::bind(oneValGet, _1, _2, Bool(true)); - - m_query[CapType::FeederEnabled] = msgSupportGetAllSetReset; - m_caps[CapType::FeederEnabled] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::FeederEnabled, (int)msg); - CapabilityPrintf(msg, enum2str(CapType::FeederEnabled), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_bFeederEnabled = mech; - return success(); - } - return CapSupGetAllReset(msg, data, m_bFeederEnabled, Bool(true)); - }; - - m_query[CapType::Duplex] = msgSupportGetAll; - m_caps[CapType::Duplex] = std::bind(oneValGet, _1, _2, Duplex::OnePass); - - m_query[CapType::DuplexEnabled] = msgSupportGetAllSetReset; - m_caps[CapType::DuplexEnabled] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::DuplexEnabled, (int)msg); - if (Msg::Set == msg) { - bool mech = data.currentItem(); - - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_duplex, &mech); - load_sane_util::log_info(mech ? L"Set1 Duplex is: true\r\n" : L"Set1 Duplex is: false\r\n", 0); - int count = count_; - if (mech && count_ >= 2) - { - count /= 2; - SET_SANE_OPT(ret, scanner_, scan_count, &count); - } - else if (!mech && count_ >= 2) - SET_SANE_OPT(ret, scanner_, scan_count, &count); - - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - BYTE dup = 1; - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_duplex, NULL, &all); - dup = all[sane_opts::RANGE_POS_CURRENT]; - - load_sane_util::log_info(dup ? L"Get Duplex is: true\r\n" : L"Get Duplex is: false\r\n", 0); - - int ret = SCANNER_ERR_OK; - int count = count_; - if (dup && count_ >= 2) - { - count /= 2; - SET_SANE_OPT(ret, scanner_, scan_count, &count); - } - else if (!dup && count_ >= 2) - SET_SANE_OPT(ret, scanner_, scan_count, &count) - - return CapSupGetAllReset(msg, data, dup, Bool(true)); - }; - - m_query[CapType::AutoFeed] = msgSupportGetAllSetReset; - m_caps[CapType::AutoFeed] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::AutoFeed, (int)msg); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - m_bAutoFeed = mech; - return success(); - } - return CapSupGetAllReset(msg, data, { false,true }, m_bAutoFeed, true, m_bAutoFeed ? 1 : 0, 1); - }; - - m_query[CapType::IImageFileFormat] = msgSupportGetAllSetReset; - m_caps[CapType::IImageFileFormat] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::IImageFileFormat, (int)msg); - SANE_FinalImgFormat now, init; - std::vector all; - GET_SANE_OPT(SANE_FinalImgFormat, scanner_, ex_final_format, NULL, &all); - init = all[sane_opts::RANGE_POS_DEFAULT]; - now = all[sane_opts::RANGE_POS_CURRENT]; - if (Msg::Set == msg || Msg::Reset == msg) { - if (Msg::Set == msg) - { - auto fmt = data.currentItem(); - if (fmt != Twpp::ImageFileFormat::Bmp && - fmt != Twpp::ImageFileFormat::Jfif && - fmt != Twpp::ImageFileFormat::Tiff) - return badValue(); - init.img_format = (SANE_ImageType)fmt; - { - if (fmt == Twpp::ImageFileFormat::Bmp) - load_sane_util::log_info(L"set CapType::IImageFileFormat = Bmp\r\n", 0); - else if (fmt == Twpp::ImageFileFormat::Jfif) - load_sane_util::log_info(L"set CapType::IImageFileFormat = Jfif\r\n", 0); - else if (fmt == Twpp::ImageFileFormat::Tiff) - load_sane_util::log_info(L"set CapType::IImageFileFormat = Tiff\r\n", 0); - } - } - else - data = Capability::createOneValue((Twpp::ImageFileFormat)init.img_format); - - m_fileXfer.setFormat((Twpp::ImageFileFormat)init.img_format); - return success(); - //if(Msg::Set == msg) - // init.img_format = (SANE_ImageType)(int)data.currentItem(); - //int ret = SCANNER_ERR_OK; - //SET_SANE_OPT(ret, scanner_, ex_final_format, &init); - //return ret == SCANNER_ERR_OK ? success() : badValue(); - } - // ImageFileFormat Now = (ImageFileFormat)(int)now.img_format, Init = (ImageFileFormat)(int)init.img_format; - ImageFileFormat Now = m_fileXfer.format() , Init = Twpp::ImageFileFormat::Bmp; - std::list vals; - UInt32 i = 0, // distance(all, init), - n = 0; // distance(all, now); - for (size_t ind = sane_opts::RANGE_POS_ENUM_BEGIN; ind < all.size(); ++ind) - { - vals.push_back((ImageFileFormat)(int)all[ind].img_format); - if (all[ind].img_format == init.img_format) - i = ind; - else if (all[ind].img_format == now.img_format) - n = ind; - } - - return cap_get_enum_values(msg, data, vals, Now, Init, n, i); - }; - - m_query[CapType::IAutomaticDeskew] = msgSupportGetAllSetReset; - m_caps[CapType::IAutomaticDeskew] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IAutomaticDeskew, (int)msg); - if (Msg::Set == msg) { - auto atuodsw = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, is_auto_deskew, (bool*)&atuodsw); - return ret == SCANNER_ERR_OK ? success() : seqError(); - } - BYTE ato = 1; - std::vector all; - GET_SANE_OPT(bool, scanner_, is_auto_deskew, NULL, &all); - ato = all[sane_opts::RANGE_POS_CURRENT]; - return CapSupGetAllReset(msg, data, ato, true); - }; - - m_query[CapType::IAutomaticRotate] = msgSupportGetAllSetReset; - m_caps[CapType::IAutomaticRotate] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IAutomaticRotate, (int)msg); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - float direction = mech ? AUTO_MATIC_ROTATE : .0f; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_text_direction, &direction); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - float direction = .0f; - BYTE am = 0; - std::vector all; - GET_SANE_OPT(float, scanner_, ex_text_direction, NULL, &all); - direction = all[sane_opts::RANGE_POS_CURRENT]; - am = IS_DOUBLE_EQUAL(direction, AUTO_MATIC_ROTATE); - return CapSupGetAllReset(msg, data, am, false); - }; - - m_query[CapType::SerialNumber] = msgSupportGetAll; - m_caps[CapType::SerialNumber] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::SerialNumber, (int)msg); - Str255 str; - std::vector all; - GET_SANE_OPT(std::string, scanner_, ex_serial, NULL, &all); - strcpy(str.data(), all[sane_opts::RANGE_POS_CURRENT].c_str()); - return CapSupGetAll(msg, data, str, str); - }; - - if (SANE_ID(ex_to_be_scan) > 0) - { - m_query[CapType::AutoScan] = msgSupportGetAllSetReset; - m_caps[CapType::AutoScan] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::AutoScan, (int)msg); - if (Msg::Set == msg || Msg::Reset == msg) { - bool val = false; - if(Msg::Set == msg) - val = (bool)data.currentItem(); - int ret = SANE_STATUS_GOOD; - m_autoscan = val; - SET_SANE_OPT(ret, scanner_, ex_to_be_scan, &val); - return ret == SANE_STATUS_GOOD ? success() : badValue(); - } - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_to_be_scan, NULL, &all); - m_autoscan = (bool)all[sane_opts::RANGE_POS_CURRENT]; - //return oneValGetSet(msg, data, (Bool)all[sane_opts::RANGE_POS_CURRENT], 0); - //data = Capability::createOneValue(CapType::AutoScan, (BYTE)all[sane_opts::RANGE_POS_CURRENT]); - //return success(); - return CapSupGetAllReset(msg, data, m_autoscan, FALSE); - }; - } - - m_query[CapType::IAutoSize] = msgSupportGetAllSetReset; - m_caps[CapType::IAutoSize] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IAutoSize, (int)msg); - CapabilityPrintf(msg, enum2str(CapType::IAutoSize), msg == Msg::Set ? to_string((int)data.currentItem()) : ""); - if (Msg::Set == msg) { - auto autosize = data.currentItem(); - bool match = autosize == AutoSize::Auto; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_auto_paper_size, &match); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_auto_paper_size, NULL, &all); - UInt16 size = all[sane_opts::RANGE_POS_CURRENT] ? (UInt16)AutoSize::Auto : (UInt16)AutoSize::None; - return CapSupGetAllReset(msg, data, { AutoSize::None, AutoSize::Auto }, size, AutoSize::None, (size == (UInt16)AutoSize::Auto) ? 1 : 0, 0); - }; - - m_query[CapType::IAutomaticBorderDetection] = msgSupportGetAllSetReset; - m_caps[CapType::IAutomaticBorderDetection] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IAutomaticBorderDetection, (int)msg); - if (Msg::Set == msg) { - auto autodetectborder = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, is_size_check, (bool*)&autodetectborder); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - Bool init = false, - erase = false; - std::vector all; - GET_SANE_OPT(bool, scanner_, is_size_check, NULL, &all); - init = (bool)all[sane_opts::RANGE_POS_DEFAULT]; - erase = (bool)all[sane_opts::RANGE_POS_CURRENT]; - return CapSupGetAllReset(msg, data, { false,true }, erase, init, erase ? 1 : 0, 0); - }; - - m_query[CapType::IAutoDiscardBlankPages] = msgSupportGetAllSetReset; - m_caps[CapType::IAutoDiscardBlankPages] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IAutoDiscardBlankPages, (int)msg); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - bool discard = mech == DiscardBlankPages::Auto; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_discard_blank_page, &discard); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_discard_blank_page, NULL, &all); - DiscardBlankPages autodiscradblank = all[sane_opts::RANGE_POS_CURRENT] ? DiscardBlankPages::Auto : DiscardBlankPages::Disabled; - return CapSupGetAllReset(msg, data, autodiscradblank, DiscardBlankPages::Disabled); - }; - - m_query[(CapType)CAP_TYPE_EX_DISCARD_BLANK_RECEIPT] = msgSupportGetAllSetReset; - m_caps[(CapType)CAP_TYPE_EX_DISCARD_BLANK_RECEIPT] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CAP_TYPE_EX_DISCARD_BLANK_RECEIPT, (int)msg); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - bool discard = mech == DiscardBlankPages::Auto; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_discard_blank_receipt, &discard); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_discard_blank_receipt, NULL, &all); - DiscardBlankPages autodiscradblank = all[sane_opts::RANGE_POS_CURRENT] ? DiscardBlankPages::Auto : DiscardBlankPages::Disabled; - return CapSupGetAllResetEx(msg, data, autodiscradblank, DiscardBlankPages::Disabled); - // return success(); - }; - - m_query[CapType::IFilter] = msgSupportGetAllSetReset; - m_caps[CapType::IFilter] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IFilter, (int)msg); - if (Msg::Set == msg) { - auto mech = data.currentItem(); - int ret = SCANNER_ERR_OK, val = to_sane_filter((Filter)mech); - SET_SANE_OPT(ret, scanner_, ex_color_filter, &val); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - int cur = FILTER_NONE, def = FILTER_NONE; - std::vector vals; - GET_SANE_OPT(int, scanner_, ex_color_filter, NULL, &vals); - - std::list vs; - Filter now = from_sane_filter(vals[sane_opts::RANGE_POS_CURRENT]), - init = from_sane_filter(vals[sane_opts::RANGE_POS_DEFAULT]); - UInt32 curInd = distance(vals, vals[sane_opts::RANGE_POS_CURRENT]), - defInd = distance(vals, vals[sane_opts::RANGE_POS_DEFAULT]);; - - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < vals.size(); ++i) - { - vs.push_back(from_sane_filter(vals[i])); - } - BYTE f = (BYTE)now; - return CapSupGetAllReset(msg, data, vs, f, init, curInd, defInd); - }; - - m_query[CapType::IBrightness] = msgSupportGetAllSetReset; - m_caps[CapType::IBrightness] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IBrightness, (int)msg); - int init = 128, l = 1, u = 255, step = 1, now = 128; - int ret = SCANNER_ERR_OK; - std::vector all; - GET_SANE_OPT(int, scanner_, bright, NULL, &all); - init = all[sane_opts::RANGE_POS_DEFAULT]; - now = all[sane_opts::RANGE_POS_CURRENT]; - l = all[sane_opts::RANGE_POS_LOWER]; - u = all[sane_opts::RANGE_POS_UPPER]; - step = all[sane_opts::RANGE_POS_STEP]; - float sf = trans_range((float)step, (float)l, (float)u, -1000.0f, 1000.0f, true), - nf = trans_range((float)now, (float)l, (float)u, -1000.0f, 1000.0f), - initf = trans_range((float)init, (float)l, (float)u, -1000.0f, 1000.0f); - switch (msg) { - case Msg::Get: - sf = 333.333f; - data = Capability::createRange(Fix32(-1000.0f), Fix32(1000.0f), Fix32(sf), Fix32(nf), Fix32(initf)); - return success(); - case Msg::GetCurrent: - data = Capability::createOneValue(Fix32(nf)); - return success(); - case Msg::GetDefault: - data = Capability::createOneValue(Fix32(initf)); - return success(); - case Msg::Set: { - auto mech = data.currentItem(); - if (mech > 1000.0f || mech < -1000.0f) - return badValue(); - initf = mech.toFloat(); - } - case Msg::Reset: - now = (int)(trans_range(initf, -1000.0f, 1000.0f, (float)l, (float)u) + .5f); - SET_SANE_OPT(ret, scanner_, bright, &now); - if (Msg::Reset == msg) - { - initf = trans_range((float)now, (float)l, (float)u, -1000.0f, 1000.0f, true); - data = Capability::createOneValue(Fix32(initf)); - } - return ret == SCANNER_ERR_OK ? success() : badValue(); - default: - return capBadOperation(); - } - }; - - m_query[CapType::IContrast] = msgSupportGetAllSetReset; - m_caps[CapType::IContrast] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IContrast, (int)msg); - int init = 4, l = 1, u = 7, step = 1, now = 4; - int ret = SCANNER_ERR_OK; - std::vector all; - GET_SANE_OPT(int, scanner_, contrast, NULL, &all); - init = all[sane_opts::RANGE_POS_DEFAULT]; - now = all[sane_opts::RANGE_POS_CURRENT]; - l = all[sane_opts::RANGE_POS_LOWER]; - u = all[sane_opts::RANGE_POS_UPPER]; - step = all[sane_opts::RANGE_POS_STEP]; - float sf = trans_range((float)step, (float)l, (float)u, -1000.0f, 1000.0f, true), - nf = trans_range((float)now, (float)l, (float)u, -1000.0f, 1000.0f), - initf = trans_range((float)init, (float)l, (float)u, -1000.0f, 1000.0f); - switch (msg) { - case Msg::Get: - // sf = 333.333f; - data = Capability::createRange(Fix32(-1000.0f), Fix32(1000.0f), Fix32(sf), Fix32(nf), Fix32(initf)); - return success(); - case Msg::GetCurrent: - data = Capability::createOneValue(Fix32(nf)); - return success(); - case Msg::GetDefault: - data = Capability::createOneValue(Fix32(initf)); - return success(); - case Msg::Set: { - auto mech = data.currentItem(); - if (mech > 1000.0f || mech < -1000.0f) - return badValue(); - initf = mech.toFloat(); - } - case Msg::Reset: - now = (int)(trans_range(initf, -1000.0f, 1000.0f, (float)l, (float)u) + .5f); - SET_SANE_OPT(ret, scanner_, contrast, &now); - if (Msg::Reset == msg) - { - initf = trans_range((float)now, (float)l, (float)u, -1000.0f, 1000.0f, true); - data = Capability::createOneValue(Fix32(initf)); - } - return ret == SCANNER_ERR_OK ? success() : badValue(); - default: - return capBadOperation(); - } - }; - - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO, (int)msg); - float init = .0f, l = .0f, u = .0f, step = .0f, now = .0f; - std::vector all; - int ret = SCANNER_ERR_OK; - GET_SANE_OPT(float, scanner_, search_hole_range, NULL, &all); - init = all[sane_opts::RANGE_POS_DEFAULT] * 100.0f; - now = all[sane_opts::RANGE_POS_CURRENT] * 100.0f; - l = all[sane_opts::RANGE_POS_LOWER] * 100.0f; - u = all[sane_opts::RANGE_POS_UPPER] * 100.0f; - step = all[sane_opts::RANGE_POS_STEP] * 100.0f; - switch (msg) { - case Msg::Get: - data = Capability::createRange((CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO, UInt32(l), UInt32(u), UInt32(step), UInt32(now), UInt32(init)); - return success(); - case Msg::GetCurrent: - data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO, UInt32(now)); - return success(); - case Msg::GetDefault: - data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO, UInt32(init)); - return success(); - case Msg::Set: { - auto mech = data.currentItem(); - if (mech > u || mech < l) - return badValue(); - init = (float)mech; - } - case Msg::Reset: - init /= 100.0f; - SET_SANE_OPT(ret, scanner_, search_hole_range, &init); - return ret == SCANNER_ERR_OK ? success() : badValue(); - default: - return capBadOperation(); - } - }; - - m_query[CapType::IGamma] = msgSupportGetAllSetReset; - m_caps[CapType::IGamma] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IGamma, (int)msg); - float init = .0f, l = .0f, u = .0f, step = .0f, now = .0f; - std::vector all; - int ret = SCANNER_ERR_OK; - GET_SANE_OPT(float, scanner_, gamma, NULL, &all); - init = all[sane_opts::RANGE_POS_DEFAULT]; - now = all[sane_opts::RANGE_POS_CURRENT]; - l = all[sane_opts::RANGE_POS_LOWER]; - u = all[sane_opts::RANGE_POS_UPPER]; - step = all[sane_opts::RANGE_POS_STEP]; - switch (msg) { - case Msg::Get: - data = Capability::createRange(Fix32(l), Fix32(u), Fix32(step), Fix32(now), Fix32(init)); - return success(); - case Msg::GetCurrent: - data = Capability::createOneValue(Fix32(now)); - return success(); - case Msg::GetDefault: - data = Capability::createOneValue(Fix32(init)); - return success(); - case Msg::Set: { - auto mech = data.currentItem(); - if (mech > u || mech < l) - return badValue(); - init = mech.toFloat(); - } - case Msg::Reset: - SET_SANE_OPT(ret, scanner_, gamma, &init); - return ret == SCANNER_ERR_OK ? success() : badValue(); - default: - return capBadOperation(); - } - }; - - m_query[CapType::CustomDsData] = msgSupportGetAll; - m_caps[CapType::CustomDsData] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::CustomDsData, (int)msg); - return CapSupGetAll(msg, data, Bool(true), Bool(true)); - }; - - m_query[CapType::DoubleFeedDetection] = msgSupportGetAllSetReset; - m_caps[CapType::DoubleFeedDetection] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::DoubleFeedDetection, (int)msg); - if (Msg::Set == msg) { - auto atuodsw = data.currentItem(); - int ret = SCANNER_ERR_OK; - bool enable = atuodsw == DoubleFeedDetection::Ultrasonic; - SET_SANE_OPT(ret, scanner_, is_ultrasonic_check, &enable); - return ret == SCANNER_ERR_OK ? success() : seqError(); - } - DoubleFeedDetection init = DoubleFeedDetection::Ultrasonic; - std::vector all; - GET_SANE_OPT(bool, scanner_, is_ultrasonic_check, NULL, &all); - BYTE ato = !all[sane_opts::RANGE_POS_CURRENT]; - init = all[sane_opts::RANGE_POS_DEFAULT] ? DoubleFeedDetection::Ultrasonic : DoubleFeedDetection::ByLength; - return CapSupGetAllReset(msg, data, ato, init); - }; - - m_query[CapType::IAutomaticCropUsesFrame] = msgSupportGetAll; - m_caps[CapType::IAutomaticCropUsesFrame] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::IAutomaticCropUsesFrame, (int)msg); - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_is_paper_auto_crop, NULL, &all); - BYTE crop = all[sane_opts::RANGE_POS_CURRENT]; - return CapSupGetAll(msg, data, crop, false); - }; - - m_query[CapType::FeederLoaded] = msgSupportGetAll; - m_caps[CapType::FeederLoaded] = [this](Msg msg, Capability& data) -> Result { - log_attr_access((int)CapType::FeederLoaded, (int)msg); - Bool paperon = scanner_->is_paper_on(); - return CapSupGetAll(msg, data, paperon, paperon); - }; - - if (SANE_ID(ex_is_page_fold) > 0) - { - m_query[CapType(CapTypeEx::CAP_TYPE_EX_FOLD)] = msgSupportGetAllSetReset; - m_caps[CapType(CapTypeEx::CAP_TYPE_EX_FOLD)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_FOLD, (int)msg); - if (Msg::Set == msg || Msg::Reset == msg) { - bool fold = false; - if (msg == Msg::Set) - fold = (bool)data.currentItem();; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_is_page_fold, &fold); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_is_page_fold, NULL, &all); - BYTE fold = all[sane_opts::RANGE_POS_CURRENT]; - return CapSupGetAllResetEx(msg, data, fold, 0); - }; - } - - if (SANE_ID(dogear_size) > 0) - { - m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST, (int)msg); - int now = 10, init = 10, l = 0, u = 100, s = 10; - std::vector all; - GET_SANE_OPT(int, scanner_, dogear_size, NULL, &all); - init = all[sane_opts::RANGE_POS_DEFAULT]; - now = all[sane_opts::RANGE_POS_CURRENT]; - l = all[sane_opts::RANGE_POS_LOWER]; - u = all[sane_opts::RANGE_POS_UPPER]; - s = all[sane_opts::RANGE_POS_STEP]; - if (Msg::Set == msg || Msg::Reset == msg) { - if (Msg::Set == msg) - { - auto mech = data.currentItem(); - if (mech < 10 || mech > 300) - return badValue(); - init = (int)(trans_range((float)mech, 10.0f, 300.0f, (float)l, (float)u) + .5f); - } - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, dogear_size, &init); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - UInt32 Now = UInt32(trans_range((float)now, (float)l, (float)u, 10.0f, 300.0f) + .5f), - Init = UInt32(trans_range((float)init, (float)l, (float)u, 10.0f, 300.0f) + .5f); - - return CapSupGetAllResetEx(msg, data, Now, Init); - }; - } - - if (SANE_ID(ex_is_paper_auto_crop) > 0) - { - m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_CROP_MODEL)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_CROP_MODEL)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_CROP_MODEL, (int)msg); - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_is_paper_auto_crop, NULL, &all); - if (Msg::Set == msg || Msg::Reset == msg) - { - bool def = all[sane_opts::RANGE_POS_DEFAULT]; - if (Msg::Set == msg) - def = data.currentItem() == 1; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_is_paper_auto_crop, &def); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - BYTE crop = all[sane_opts::RANGE_POS_CURRENT]; - return CapSupGetAll(msg, data, crop, all[sane_opts::RANGE_POS_DEFAULT]); - }; - } - - if (SANE_ID(ex_multiout_type) > 0) - { - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE, (int)msg); - int cur = MULTI_OUT_NONE, def = MULTI_OUT_NONE; - std::vector all; - GET_SANE_OPT(int, scanner_, ex_multiout_type, NULL, &all); - cur = all[sane_opts::RANGE_POS_CURRENT]; - def = all[sane_opts::RANGE_POS_DEFAULT]; - if (Msg::Set == msg || Msg::Reset == msg) { - auto mech = def; - if (msg == Msg::Set) - mech = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_multiout_type, &mech); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - Int32 now = cur, init = def, ind = 0, - curInd = distance(all, cur), - defInd = distance(all, def); - std::list vals; - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) - vals.push_back(all[i]); - return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); - }; - } - - if (SANE_ID(ex_to_be_scan) > 0) - { - m_query[CapType(CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN)] = msgSupportGetAllSetReset; - m_caps[CapType(CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN, (int)msg); - if (Msg::Set == msg || Msg::Reset == msg) { - auto tobe = false; - if (msg == Msg::Set) - tobe = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_to_be_scan, &tobe); - return ret == SCANNER_ERR_OK ? success() : seqError(); - } - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_to_be_scan, NULL, &all); - BYTE tobe = all[sane_opts::RANGE_POS_CURRENT]; - return CapSupGetAllResetEx(msg, data, tobe, 0); - }; - } - - if (SANE_ID(ex_scan_with_hole) > 0) - { - m_query[CapType(CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE)] = msgSupportGetAllSetReset; - m_caps[CapType(CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE, (int)msg); - if (Msg::Set == msg || Msg::Reset == msg) { - auto tobe = false; - if (msg == Msg::Set) - tobe = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_scan_with_hole, &tobe); - return ret == SCANNER_ERR_OK ? success() : seqError(); - } - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_scan_with_hole, NULL, &all); - BYTE tobe = all[sane_opts::RANGE_POS_CURRENT];; - return CapSupGetAllResetEx(msg, data, tobe, 0); - }; - } - - if (SANE_ID(ex_device_code) > 0) - { - m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_ENCODE)] = msgSupportGetAll; - m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_ENCODE)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_ENCODE, (int)msg); - std::vector all; - GET_SANE_OPT(std::string, scanner_, ex_device_code, NULL, &all); - Str255 str; - str.setData(all[sane_opts::RANGE_POS_CURRENT].c_str(), 32); - data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_ENCODE, str); - return success(); - }; - } - - if (SANE_ID(ex_power) > 0) - { - m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_POWER_LEVEL)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_POWER_LEVEL)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_POWER_LEVEL, (int)msg); - int cur = SANE_POWER_MINUTES_30, def = SANE_POWER_MINUTES_30; - std::vector all; - GET_SANE_OPT(int, scanner_, ex_power, NULL, &all); - cur = all[sane_opts::RANGE_POS_CURRENT]; - def = all[sane_opts::RANGE_POS_DEFAULT]; - if (Msg::Set == msg || Msg::Reset == msg) { - if (msg == Msg::Set) - def = data.currentItem(); - - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_power, &def); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - UInt32 now = cur, init = def, ind = 0, - curInd = distance(all, cur), - defInd = distance(all, def); - std::list vals; - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) - { - vals.push_back(all[i]); - } - return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); - }; - } - - if (SANE_ID(ex_fill_background) > 0) - { - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD, (int)msg); - if (Msg::Set == msg) { - auto convex = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_fill_background, (bool*)&convex); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - bool val = false, cur = false; - Bool init = false, - erase = false; - std::vector all; - GET_SANE_OPT(bool, scanner_, ex_fill_background, NULL, &all); - init = (bool)all[sane_opts::RANGE_POS_DEFAULT]; - erase = (bool)all[sane_opts::RANGE_POS_CURRENT]; - return CapSupGetAllResetEx(msg, data, { false,true }, erase, init, erase ? 1 : 0, 0); - }; - } - - if (SANE_ID(ex_sharpen) > 0) - { - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_SHARPEN, (int)msg); - int cur = MULTI_OUT_NONE, def = MULTI_OUT_NONE; - std::vector all; - GET_SANE_OPT(int, scanner_, ex_sharpen, NULL, &all); - cur = all[sane_opts::RANGE_POS_CURRENT]; - def = all[sane_opts::RANGE_POS_DEFAULT]; - if (Msg::Set == msg || Msg::Reset == msg) { - auto mech = def; - if (msg == Msg::Set) - mech = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_sharpen, &mech); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - Int32 now = cur, init = def, - curInd = distance(all, cur), - defInd = distance(all, def); - std::list vals; - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) - vals.push_back(all[i]); - return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); - }; - } - - if (SANE_ID(ex_color_enhance) > 0) - { - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR, (int)msg); - int cur = FILTER_NONE, def = FILTER_NONE; - std::vector vals; - GET_SANE_OPT(int, scanner_, ex_color_enhance, NULL, &vals); - cur = vals[sane_opts::RANGE_POS_CURRENT]; - def = vals[sane_opts::RANGE_POS_DEFAULT]; - if (Msg::Set == msg || Msg::Reset == msg) { - if (Msg::Set == msg) - def = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_color_filter, &def); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - - std::list vs; - Filter now = from_sane_filter(cur), init = from_sane_filter(def); - UInt32 curInd = distance(vals, cur), defInd = distance(vals, def); - - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < vals.size(); ++i) - vs.push_back(from_sane_filter(vals[i])); - UInt32 val = (UInt32)now; - return CapSupGetAllResetEx(msg, data, vs, val, init, curInd, defInd); - }; - } - - init_support_caps_ex(); - - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_HARDWARE_VERSION] = msgSupportGetAll; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_HARDWARE_VERSION] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_HARDWARE_VERSION, (int)msg); - std::vector all; - GET_SANE_OPT(std::string, scanner_, ex_hardware_version, NULL, &all); - Str255 str; - strcpy(str.data(), all[sane_opts::RANGE_POS_CURRENT].c_str()); - data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_HARDWARE_VERSION, str); - return success(); - }; - - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_IP] = msgSupportGetAll; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_IP] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_IP, (int)msg); - std::vector all; - GET_SANE_OPT(std::string, scanner_, ex_ip, NULL, &all); - Str255 str; - strcpy(str.data(), all[sane_opts::RANGE_POS_CURRENT].c_str()); - data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_IP, str); - return success(); // CapSupGetAll(msg, data, str, str); - }; - -#define SET_EXISTING_EXTENSION(name, cap) \ - if(m_query.count((CapType)CAP_EX_SANE_##name)) \ - { \ - m_query[(CapType)cap] = m_query[(CapType)CAP_EX_SANE_##name]; \ - m_caps[(CapType)cap] = m_caps[CapType((int)CAP_EX_SANE_##name)]; \ - } - - SET_EXISTING_EXTENSION(is_swap, CapTypeEx::CAP_TYPE_EX_FLIP); - SET_EXISTING_EXTENSION(is_rotate_bkg180, CapTypeEx::CAP_TYPE_EX_ROTATE_BKG_180); - SET_EXISTING_EXTENSION(is_filling_color, CapTypeEx::CAP_TYPE_EX_FILL_BLACK_BKG); - SET_EXISTING_EXTENSION(margin, CapTypeEx::CAP_TYPE_EX_EDGE_IDENT); - SET_EXISTING_EXTENSION(anti_noise, CapTypeEx::CAP_TYPE_EX_ANTI_NOISE); - SET_EXISTING_EXTENSION(threshold, CapTypeEx::CAP_TYPE_EX_THRESHOLD); - SET_EXISTING_EXTENSION(is_erase_hole, CapTypeEx::CAP_TYPE_EX_FILL_HOLE); - SET_EXISTING_EXTENSION(is_noise_modify, CapTypeEx::CAP_TYPE_EX_DETACH_NOISE); - SET_EXISTING_EXTENSION(noise_threshold, CapTypeEx::CAP_TYPE_EX_DETACH_NOISE_THRESHOLD); - SET_EXISTING_EXTENSION(erase_multiout_red, CapTypeEx::CAP_TYPE_EX_RID_RED); - SET_EXISTING_EXTENSION(erase_paper_red, CapTypeEx::CAP_TYPE_EX_RID_RED_HSV); - SET_EXISTING_EXTENSION(is_check_skew, CapTypeEx::CAP_TYPE_EX_SCREW_DETECT); - SET_EXISTING_EXTENSION(skew_range, CapTypeEx::CAP_TYPE_EX_SCREW_DETECT_LEVEL); - SET_EXISTING_EXTENSION(is_check_staple, CapTypeEx::CAP_TYPE_EX_STAPLE_DETECT); - SET_EXISTING_EXTENSION(is_check_dogear, CapTypeEx::CAP_TYPE_EX_DOGEAR_DETECT); - SET_EXISTING_EXTENSION(deep_sample, CapTypeEx::CAP_TYPE_EX_DARK_SAMPLE); - SET_EXISTING_EXTENSION(is_split, CapTypeEx::CAP_TYPE_EX_IMAGE_SPLIT); - SET_EXISTING_EXTENSION(is_erase_background, CapTypeEx::CAP_TYPE_EX_FADE_BKG); - SET_EXISTING_EXTENSION(background_color_range, CapTypeEx::CAP_TYPE_EX_FADE_BKG_VALUE); - SET_EXISTING_EXTENSION(is_size_check, CapTypeEx::CAP_TYPE_EX_SIZE_DETECT); - SET_EXISTING_EXTENSION(is_multiout, CapTypeEx::CAP_TYPE_EX_MULTI_OUT); -} -void huagao_ds::init_support_caps_ex(void) -{ -#define SET_SANE_CAP_ENUM(ctype, ttype, name) \ - m_query[(CapType)CAP_EX_SANE_##name] = msgSupportGetAllSetReset; \ - m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \ - log_attr_access((int)CAP_EX_SANE_##name, (int)msg); \ - ctype now, init; \ - std::vector all; \ - GET_SANE_OPT(ctype, scanner_, name, NULL, &all); \ - init = all[sane_opts::RANGE_POS_DEFAULT]; \ - now = all[sane_opts::RANGE_POS_CURRENT]; \ - if (msg == Msg::Set || msg == Msg::Reset) \ - { \ - if (msg == Msg::Set) \ - { \ - ttype v = data.currentItem(); \ - copy_type(init, v); \ - } \ - int ret = SCANNER_ERR_OK; \ - SET_SANE_OPT(ret, scanner_, name, &init); \ - if(msg == Msg::Reset) \ - { \ - ttype v; \ - copy_type(v, init); \ - data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, v); \ - } \ - return ret == SCANNER_ERR_OK ? success() : badValue(); \ - } \ - else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \ - { \ - ttype t; \ - if(msg == Msg::GetCurrent) \ - copy_type(t, now); \ - else \ - copy_type(t, init); \ - data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, t); \ - return { ReturnCode::Success, ConditionCode::Success }; \ - } \ - else \ - { \ - std::list vals; \ - UInt32 ni = distance(all, now), ii = distance(all, init); \ - for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) \ - { \ - ttype t; \ - copy_type(t, all[i]); \ - vals.push_back(t); \ - } \ - data = Capability::createEnumeration((CapType)CAP_EX_SANE_##name, vals, ni, ii); \ - return { ReturnCode::Success, ConditionCode::Success }; \ - } \ - }; \ - -#define SET_SANE_CAP_RANGE(ctype, ttype, name) \ - m_query[(CapType)CAP_EX_SANE_##name] = msgSupportGetAllSetReset; \ - m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \ - log_attr_access((int)CAP_EX_SANE_##name, (int)msg); \ - ctype now, init, lower, upper, step; \ - std::vector all; \ - GET_SANE_OPT(ctype, scanner_, name, NULL, &all); \ - now = all[sane_opts::RANGE_POS_CURRENT]; \ - init = all[sane_opts::RANGE_POS_DEFAULT]; \ - lower = all[sane_opts::RANGE_POS_LOWER]; \ - upper = all[sane_opts::RANGE_POS_UPPER]; \ - step = all[sane_opts::RANGE_POS_STEP]; \ - if (msg == Msg::Set || msg == Msg::Reset) \ - { \ - if (msg == Msg::Set) \ - { \ - ttype v = data.currentItem(); \ - copy_type(init, v); \ - } \ - int ret = SCANNER_ERR_OK; \ - SET_SANE_OPT(ret, scanner_, name, &init); \ - if(msg == Msg::Reset) \ - { \ - ttype v; \ - copy_type(v, init); \ - data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, v); \ - } \ - return ret == SCANNER_ERR_OK ? success() : badValue(); \ - } \ - else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \ - { \ - ttype t; \ - if(msg == Msg::GetCurrent) \ - copy_type(t, now); \ - else \ - copy_type(t, init); \ - data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, t); \ - return { ReturnCode::Success, ConditionCode::Success }; \ - } \ - else \ - { \ - ttype Now, Init, Lower, Upper, Step; \ - copy_type(Now, now); \ - copy_type(Init, init); \ - copy_type(Lower, lower); \ - copy_type(Upper, upper); \ - copy_type(Step, step); \ - data = Capability::createRange((CapType)CAP_EX_SANE_##name, Lower, Upper, Step, Now, Init);\ - return { ReturnCode::Success, ConditionCode::Success }; \ - } \ - }; \ - -#define SET_SANE_CAP(ctype, ttype, name) \ - m_query[(CapType)CAP_EX_SANE_##name] = msgSupportGetAllSetReset; \ - m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \ - log_attr_access((int)CAP_EX_SANE_##name, (int)msg); \ - ctype now, init; \ - std::vector all; \ - GET_SANE_OPT(ctype, scanner_, name, NULL, &all); \ - now = all[sane_opts::RANGE_POS_CURRENT]; \ - init = all[sane_opts::RANGE_POS_DEFAULT]; \ - if (msg == Msg::Set || msg == Msg::Reset) \ - { \ - if (msg == Msg::Set) \ - { \ - ttype v = data.currentItem(); \ - copy_type(init, v); \ - } \ - int ret = SCANNER_ERR_OK; \ - SET_SANE_OPT(ret, scanner_, name, &init); \ - if(msg == Msg::Reset) \ - { \ - ttype v; \ - copy_type(v, init); \ - data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, v); \ - } \ - return ret == SCANNER_ERR_OK ? success() : badValue(); \ - } \ - else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \ - { \ - ttype t; \ - if(msg == Msg::GetCurrent) \ - copy_type(t, now); \ - else \ - copy_type(t, init); \ - data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, t); \ - return { ReturnCode::Success, ConditionCode::Success }; \ - } \ - else \ - { \ - ttype Now; \ - copy_type(Now, now); \ - data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, Now); \ - return { ReturnCode::Success, ConditionCode::Success }; \ - } \ - }; \ - -#define ADD_SANE_CAP(name) \ - do \ - { \ - int sn = scanner_->sane_opt_id_##name(); \ - if(sn == -1) break; \ - value_type type; \ - value_limit limit; \ - if(!scanner_->get_option_info(sn, &type, &limit, NULL)) break; \ - if(limit == VAL_LIMIT_ENUM) \ - { \ - if(type == VAL_TYPE_INT) \ - { \ - SET_SANE_CAP_ENUM(int, Int32, name) \ - } \ - else if(type == VAL_TYPE_FLOAT) \ - { \ - SET_SANE_CAP_ENUM(float, Fix32, name) \ - } \ - else \ - { \ - SET_SANE_CAP_ENUM(std::string, Str255, name) \ - } \ - } \ - else if(limit == VAL_LIMIT_RANGE) \ - { \ - if(type == VAL_TYPE_INT) \ - { \ - SET_SANE_CAP_RANGE(int, Int32, name) \ - } \ - else if(type == VAL_TYPE_FLOAT) \ - { \ - SET_SANE_CAP_RANGE(float, Fix32, name) \ - } \ - } \ - else \ - { \ - if(type == VAL_TYPE_BOOL) \ - { \ - m_query[(CapType)CAP_EX_SANE_##name] = msgSupportGetAllSetReset; \ - m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \ - log_attr_access((int)CAP_EX_SANE_##name, (int)msg); \ - std::vector all; \ - bool now = false, init = false; \ - GET_SANE_OPT(bool, scanner_, name, NULL, &all); \ - now = all[sane_opts::RANGE_POS_CURRENT]; \ - init = all[sane_opts::RANGE_POS_DEFAULT]; \ - if (msg == Msg::Set || msg == Msg::Reset) \ - { \ - if (msg == Msg::Set) \ - init = (bool)data.currentItem(); \ - int ret = SCANNER_ERR_OK; \ - SET_SANE_OPT(ret, scanner_, name, &init); \ - return ret == SCANNER_ERR_OK ? success() : badValue(); \ - } \ - else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \ - { \ - Bool t; \ - if(msg == Msg::GetCurrent) \ - t = now; \ - else \ - t = init; \ - data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, t); \ - return { ReturnCode::Success, ConditionCode::Success }; \ - } \ - else \ - { \ - UInt32 ni = now ? 1 : 0, ii = init ? 1 : 0; \ - data = Capability::createEnumeration((CapType)CAP_EX_SANE_##name, { FALSE, TRUE }, ni, ii); \ - return { ReturnCode::Success, ConditionCode::Success }; \ - } \ - }; \ - } \ - else if(type == VAL_TYPE_INT) \ - { \ - SET_SANE_CAP(int, Int32, name) \ - } \ - else if(type == VAL_TYPE_FLOAT) \ - { \ - SET_SANE_CAP(float, Fix32, name) \ - } \ - else \ - { \ - SET_SANE_CAP(std::string, Str255, name) \ - } \ - } \ - }while (0); - - // setting items ... - ADD_SANE_CAP(is_multiout); - ADD_SANE_CAP(multiout_type); - ADD_SANE_CAP(color_mode); - ADD_SANE_CAP(erase_color); - ADD_SANE_CAP(erase_multiout_red); - ADD_SANE_CAP(erase_paper_red); - ADD_SANE_CAP(is_erase_background); - ADD_SANE_CAP(background_color_range); - ADD_SANE_CAP(sharpen); - ADD_SANE_CAP(erase_morr); - ADD_SANE_CAP(erase_grids); - ADD_SANE_CAP(error_extend); - ADD_SANE_CAP(is_noise_modify); - ADD_SANE_CAP(noise_threshold); - ADD_SANE_CAP(paper); - ADD_SANE_CAP(is_custom_area); - ADD_SANE_CAP(curstom_area_l); - ADD_SANE_CAP(curstom_area_r); - ADD_SANE_CAP(curstom_area_t); - ADD_SANE_CAP(curstom_area_b); - ADD_SANE_CAP(is_size_check); - ADD_SANE_CAP(page); - ADD_SANE_CAP(blank_page_threshold); - ADD_SANE_CAP(resolution); - ADD_SANE_CAP(image_quality); - ADD_SANE_CAP(is_swap); - ADD_SANE_CAP(is_split); - ADD_SANE_CAP(is_auto_deskew); - ADD_SANE_CAP(is_custom_gamma); - ADD_SANE_CAP(bright); - ADD_SANE_CAP(contrast); - ADD_SANE_CAP(gamma); - ADD_SANE_CAP(is_erase_black_frame); - ADD_SANE_CAP(deep_sample); - ADD_SANE_CAP(threshold); - ADD_SANE_CAP(anti_noise); - ADD_SANE_CAP(margin); - ADD_SANE_CAP(fill_background); - ADD_SANE_CAP(is_anti_permeate); - ADD_SANE_CAP(anti_permeate_level); - ADD_SANE_CAP(is_erase_hole); - ADD_SANE_CAP(search_hole_range); - ADD_SANE_CAP(is_filling_color); - ADD_SANE_CAP(is_ultrasonic_check); - ADD_SANE_CAP(is_check_staple); - ADD_SANE_CAP(scan_mode); - ADD_SANE_CAP(scan_count); - ADD_SANE_CAP(text_direction); - ADD_SANE_CAP(is_rotate_bkg180); - ADD_SANE_CAP(is_check_dogear); - ADD_SANE_CAP(dogear_size); - ADD_SANE_CAP(is_check_skew); - ADD_SANE_CAP(skew_range); - ADD_SANE_CAP(black_white_threshold); - ADD_SANE_CAP(is_photo_mode); - ADD_SANE_CAP(double_feed_handle); - ADD_SANE_CAP(scan_when_paper_on); - ADD_SANE_CAP(feed_strength); - ADD_SANE_CAP(power_scheme); - ADD_SANE_CAP(is_auto_strength); - ADD_SANE_CAP(feed_strength_value); - ADD_SANE_CAP(is_reverse_bw); - ADD_SANE_CAP(is_erase_hole_l); // Ƴ - - ADD_SANE_CAP(search_hole_range_l); // Χ - - ADD_SANE_CAP(is_erase_hole_r); // Ƴ - - ADD_SANE_CAP(search_hole_range_r); // Χ - - ADD_SANE_CAP(is_erase_hole_t); // Ƴ - - ADD_SANE_CAP(search_hole_range_t); // Χ - - ADD_SANE_CAP(is_erase_hole_b); // Ƴ - - ADD_SANE_CAP(search_hole_range_b); // Χ - - ADD_SANE_CAP(fold_direction); // ۷ - //ADD_SANE_CAP(fold_type); - ADD_SANE_CAP(color_correction); -} -std::wstring huagao_ds::get_config_file(void) -{ - char* tmp = getenv("LOCALAPPDATA"); - if (tmp) - { - std::wstring str(L""); - std::string path(tmp); - - path += std::string("\\") + PRODUCT_VENDOR + "Scan\\config\\debug.cfg"; - - return std::move(load_sane_util::ansi2unic(path.c_str())); - } - else - { - wchar_t path[MAX_PATH] = { 0 }, * name = NULL; - - GetModuleFileNameW(me_, path, _countof(path) - 1); - name = wcsrchr(path, L'\\'); - if (name++ == NULL) - name = path; - wcscpy_s(name, _countof(path) - 1 - (name - path), L"debug.cfg"); - - return path; - } -} -std::wstring huagao_ds::get_config_value(const wchar_t* sec, const wchar_t* key) -{ - wchar_t v[256] = { 0 }; - std::wstring cfg_f(get_config_file()); - - if(!cfg_f.empty()) - GetPrivateProfileStringW(sec, key, L"", v, _countof(v) - 1, get_config_file().c_str()); - - return v; -} -DWORD huagao_ds::get_config_number(const wchar_t* sec, const wchar_t* key) -{ - std::wstring cfg_f(get_config_file()); - - if (cfg_f.empty()) - return 0; - else - return GetPrivateProfileIntW(sec, key, 0, get_config_file().c_str()); -} -int huagao_ds::handle_scanner_event(int ev, bool from_event_proc) -{ - static int count_0 = 0; - ReturnCode rc = ReturnCode::Success; - int ret = 0; - - if (ev == 0) - count_0++; - else - { - wchar_t msg[128] = { 0 }; - if (count_0) - swprintf_s(msg, _countof(msg) - 1, L"[%x]handle_scanner_event(0x0 +%d)\r\nds::eventProcess(0x%x)\r\n", GetCurrentThreadId(), count_0, ev); - else - swprintf_s(msg, _countof(msg) - 1, L"[%x]handle_scanner_event(0x%x)\r\n", GetCurrentThreadId(), ev); - load_sane_util::log_info(msg, 0); - count_0 = 0; - } - switch (ev) - { - case SANE_EVENT_WORKING: - scanner_status_ = SCANNER_STATUS_SCANNING; - rc = notifyXferReady(); - if (!Twpp::success(rc)) - { - wchar_t msg[128] = { 0 }; - swprintf_s(msg, _countof(msg) - 1, L"[%x]Warning: change state to XferReady failed with error %d while in state(%d), STOP scanning ...\r\n", GetCurrentThreadId(), rc, state()); - load_sane_util::log_info(msg, 0); - - // we stop scanning here ... - scanner_->stop(); - } - break; - case SANE_EVENT_UI_CLOSE_CANCEL: - scanner_->stop(); - //notifyCloseCancel(); // ޸ȿ"ȡ"ťUIBUG - added on 2023-02-14 - //break; - case SANE_EVENT_UI_CLOSE_NORMAL: - scanner_->ui_hide(); - case SANE_EVENT_SCAN_FINISHED: - scanner_status_ = SCANNER_STATUS_STOPPED; - //notifyCloseOk(); - //break; - case SANE_EVENT_UI_CLOSE_SETTING: - notifyCloseCancel(); - if (ev == SANE_EVENT_UI_CLOSE_SETTING) - { - rc = notifyXferReady(); // ÷Ҫ֪ͨ FAINT :( - modified on 2022-10-20 - if (!Twpp::success(rc)) - { - wchar_t msg[128] = { 0 }, unk[20] = { 0 }; - swprintf_s(msg, _countof(msg) - 1, L"[%x]yscan: notifyXferReady failed after setting UI closed with error %d\r\n", GetCurrentThreadId(), rc); - load_sane_util::log_info(msg, 0); - } - } - break; - case SANE_EVENT_UI_SCAN_COMMAND: - if (m_bIndicator) - scanner_->ui_show_progress(NULL); - else - scanner_->ui_hide(); - scanner_status_ = SCANNER_STATUS_SCAN_1; - app_trigger_event_ = false; - if ((ret = scanner_->start())) - { - wchar_t msg[128] = { 0 }, unk[20] = { 0 }; - swprintf_s(msg, _countof(msg) - 1, L"[%x - %s]Fatal: start scanning from setting UI failed with error %d\r\n", GetCurrentThreadId(), desc_state(state(), unk), ret); - load_sane_util::log_info(msg, 0); - - scanner_status_ = SCANNER_STATUS_STOPPED; - rc = notifyCloseCancel(); - if (Twpp::success(rc)) - { - scanner_status_ = SCANNER_STATUS_READY; - } - else - { - swprintf_s(msg, _countof(msg) - 1, L"[%x]Warning: notifyCloseCancel failed with error %d after start scanning failed\r\n", GetCurrentThreadId(), rc, state()); - load_sane_util::log_info(msg, 0); - } - } - break; - } - - return 0; -} -int huagao_ds::get_scanned_image_count(DWORD timeout) -{ - int cnt = scanner_->get_scanned_images(timeout); - - //if (cnt == -1) - //{ - // // This is a special value indicates the scanning is over - // cnt = 0; - // scanner_->ui_hide(); - // notifyCloseCancel(); - //} - - return cnt; -} -void huagao_ds::trigger_ProcessEvent(Twpp::DataGroup dg, Twpp::Dat dat, Twpp::Msg msg) -{ - ReturnCode rc; - - if (state() == DsState::Enabled && scanner_status_ >= SCANNER_STATUS_SCAN_1) // in scanning events ... - { - // here ensure APP enter into XferImage process ... - if (!app_trigger_event_ && scanner_status_ == SCANNER_STATUS_STOPPED) - { - // scanning stopped, reset APP state to ready ... - scanner_status_ = SCANNER_STATUS_READY; - rc = notifyCloseCancel(); - if (!Twpp::success(rc)) - { - wchar_t info[128] = { 0 }, unk[20] = { 0 }; - swprintf_s(info, _countof(info) - 1, L"[%x]Warning: notifyCloseCancel failed with error %s!\r\n", GetCurrentThreadId(), desc_return_code(rc, unk)); - load_sane_util::log_info(info, 0); - } - } - else - { - // start scanning, expect frist TRIPLE is ProcessEvent ... - if (dg == DataGroup::Control && dat == Dat::Event && msg == Msg::ProcessEvent && scanner_status_ == SCANNER_STATUS_SCAN_1) - { - app_trigger_event_ = true; // nothing else to do - load_sane_util::log_info(L"Good! first event is (Control, Event, ProcessEvent) after start scanning ^_^.\r\n", 0); - } - else if(!app_trigger_event_) - { - int ev = 0; - - if (scanner_status_ == SCANNER_STATUS_SCAN_1) - load_sane_util::log_info(L"Sorry, first event is not (Control, Event, ProcessEvent) after start scanning, we takeover it!\r\n", 0); - if (scanner_.get()) - { - ev = scanner_->get_event(); - if (ev) - handle_scanner_event(ev, true); - } - } - } - } - else if (state() >= DsState::XferReady && scanner_status_ == SCANNER_STATUS_STOPPED) - { - // here ensure APP return to ready state ... - if (scanner_.get() && scanner_->get_scanned_images(0) == 0) - { - rc = notifyCloseCancel(); - if (!Twpp::success(rc)) - { - wchar_t info[128] = { 0 }, unk[20] = { 0 }; - swprintf_s(info, _countof(info) - 1, L"[%x]Warning: notifyCloseCancel failed with error %s when scanner is stopped!\r\n", GetCurrentThreadId(), desc_return_code(rc, unk)); - load_sane_util::log_info(info, 0); - } - } - } -} - diff --git a/twain/twain/huagaods.hpp b/twain/twain/huagaods.hpp deleted file mode 100644 index 546775e..0000000 --- a/twain/twain/huagaods.hpp +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef SIMPLEDS_HPP -#define SIMPLEDS_HPP - -#include -#include -#include -#include -#include -#include -#include "twpp.hpp" -#include "../load_sane.h" - -namespace std { - - template<> - struct hash { - size_t operator()(Twpp::CapType cap) const { - return hash()(static_cast(cap)); - } - }; - -} - -class twain_ui; - -enum scanner_status -{ - SCANNER_STATUS_NOT_INIT = 0, // has not call identityOpenDs or called identityCloseDs - SCANNER_STATUS_READY, // called identityOpenDs - SCANNER_STATUS_SCAN_1, // scanner_->start() should be called - SCANNER_STATUS_SCANNING, // received SANE_EVENT_WORKING - SCANNER_STATUS_STOPPED, // received SANE_EVENT_SCAN_FINISHED -}; -class huagao_ds : public Twpp::SourceFromThis { - std::unordered_map> m_caps; - std::unordered_map m_query; - std::unique_ptr scanner_; - Twpp::SetupFileXfer m_fileXfer; - Twpp::XferMech m_capXferMech = Twpp::XferMech::Native; - std::unique_ptr memoryinfo; - bool m_memoryfalg = true; - bool m_bFeederEnabled = true; - bool m_bAutoFeed = true; - HANDLE singleton_ = NULL; - Twpp::Bool m_autoscan = true; - int automaticcolortype_ = 0; - bool multi_out_ = false; - bool m_bIndicator = true; - int m_jpegQuality = 80; - Twpp::Compression m_compression = Twpp::Compression::None; - SANE_Parameters* cur_head_; - int dpi_; - int scanner_status_; - bool xfer_ready_failed_; - bool log_all_triple_; - bool app_trigger_event_; - - int count_; - static std::string get_hidedlg_path(void); - static void showmsg(const char* msg, int err); - static int __stdcall on_scanner_event(int ev, void* param); - - void CapabilityPrintf(Twpp::Msg msg, std::string capability, std::string value = ""); - Twpp::Result capCommon(const Twpp::Identity& origin, Twpp::Msg msg, Twpp::Capability& data); - Twpp::Result showTwainUI(Twpp::UserInterface& data, bool bUiOnly = false); - void init_support_caps(void); - void init_support_caps_ex(void); - std::wstring get_config_file(void); - std::wstring get_config_value(const wchar_t* sec, const wchar_t* key); - DWORD get_config_number(const wchar_t* sec, const wchar_t* key); - int handle_scanner_event(int ev, bool from_event_proc = true); - int get_scanned_image_count(DWORD timeout); - void trigger_ProcessEvent(Twpp::DataGroup dg, Twpp::Dat dat, Twpp::Msg msg); - - typedef struct _pending_xfer - { - IScanImg* img; - unsigned int off; - - struct _pending_xfer() : img(NULL), off(0) - {} - void clear(void) - { - if (img) - img->release(); - img = NULL; - off = 0; - } - }PENDXFER; - PENDXFER pending_xfer_; - -public: - huagao_ds(); - virtual ~huagao_ds(); - - static const Twpp::Identity& defaultIdentity() noexcept; - static Twpp::Result selectIdentity(Twpp::Identity& ident) noexcept; - static Twpp::ConditionCode condition_code_from_hg_error(int hgerr); - - // SourceFromThis interface -protected: - typedef Twpp::SourceFromThis Base; - - virtual Twpp::Result capabilityGet(const Twpp::Identity& origin, Twpp::Capability& data) override; - virtual Twpp::Result capabilityGetCurrent(const Twpp::Identity& origin, Twpp::Capability& data) override; - virtual Twpp::Result capabilityGetDefault(const Twpp::Identity& origin, Twpp::Capability& data) override; - virtual Twpp::Result capabilityQuerySupport(const Twpp::Identity& origin, Twpp::Capability& data) override; - virtual Twpp::Result capabilityReset(const Twpp::Identity& origin, Twpp::Capability& data) override; - virtual Twpp::Result capabilityResetAll(const Twpp::Identity& origin) override; - virtual Twpp::Result capabilitySet(const Twpp::Identity& origin, Twpp::Capability& data) override; - virtual Twpp::Result eventProcess(const Twpp::Identity& origin, Twpp::Event& data) override; - virtual Twpp::Result deviceEventGet(const Twpp::Identity& origin, Twpp::DeviceEvent& data) override; - virtual Twpp::Result identityOpenDs(const Twpp::Identity& origin) override; - virtual Twpp::Result identityCloseDs(const Twpp::Identity& origin) override; - virtual Twpp::Result pendingXfersGet(const Twpp::Identity& origin, Twpp::PendingXfers& data) override; - virtual Twpp::Result pendingXfersEnd(const Twpp::Identity& origin, Twpp::PendingXfers& data) override; - virtual Twpp::Result pendingXfersReset(const Twpp::Identity& origin, Twpp::PendingXfers& data) override; - virtual Twpp::Result setupMemXferGet(const Twpp::Identity& origin, Twpp::SetupMemXfer& data) override; - virtual Twpp::Result userInterfaceDisable(const Twpp::Identity& origin, Twpp::UserInterface& data) override; - virtual Twpp::Result userInterfaceEnable(const Twpp::Identity& origin, Twpp::UserInterface& data) override; - virtual Twpp::Result userInterfaceEnableUiOnly(const Twpp::Identity& origin, Twpp::UserInterface& data) override; - virtual Twpp::Result extImageInfoGet(const Twpp::Identity& origin, Twpp::ExtImageInfo& data) override; - virtual Twpp::Result imageInfoGet(const Twpp::Identity& origin, Twpp::ImageInfo& data) override; - virtual Twpp::Result imageLayoutGet(const Twpp::Identity& origin, Twpp::ImageLayout& data) override; - virtual Twpp::Result imageLayoutGetDefault(const Twpp::Identity& origin, Twpp::ImageLayout& data) override; - virtual Twpp::Result imageLayoutSet(const Twpp::Identity& origin, Twpp::ImageLayout& data) override; - virtual Twpp::Result imageLayoutReset(const Twpp::Identity& origin, Twpp::ImageLayout& data) override; - virtual Twpp::Result imageMemXferGet(const Twpp::Identity& origin, Twpp::ImageMemXfer& data) override; - virtual Twpp::Result imageNativeXferGet(const Twpp::Identity& origin, Twpp::ImageNativeXfer& data) override; - virtual Twpp::Result pendingXfersStopFeeder(const Twpp::Identity& origin, Twpp::PendingXfers& data) override; - virtual Twpp::Result imageFileXferGet(const Twpp::Identity& origin) override; - virtual Twpp::Result setupFileXferGet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) override; - virtual Twpp::Result setupFileXferGetDefault(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) override; - virtual Twpp::Result setupFileXferSet(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) override; - virtual Twpp::Result setupFileXferReset(const Twpp::Identity& origin, Twpp::SetupFileXfer& data) override; - virtual Twpp::Result call(const Twpp::Identity& origin, Twpp::DataGroup dg, Twpp::Dat dat, Twpp::Msg msg, void* data) override; - virtual Twpp::Result customDataGet(const Twpp::Identity& origin, Twpp::CustomData& data) override; - virtual Twpp::Result customDataSet(const Twpp::Identity& origin, Twpp::CustomData& data) override; - -public: - void SetResoluton(const char* path, int resolution); -}; - -#endif // SIMPLEDS_HPP diff --git a/twain/twain/twain_2.4.h b/twain/twain/twain_2.4.h deleted file mode 100644 index 0d1ce92..0000000 --- a/twain/twain/twain_2.4.h +++ /dev/null @@ -1,2265 +0,0 @@ -/* ======================================================================== *\ - - Copyright (C) 2007 TWAIN Working Group: Adobe Systems Incorporated, - AnyDoc Software Inc., Eastman Kodak Company, Fujitsu Computer Products - of America, JFL Peripheral Solutions Inc., Ricoh Corporation, and - Xerox Corporation. All rights reserved. - - Copyright (C) 1991, 1992 TWAIN Working Group: Aldus, Caere, Eastman-Kodak, - Hewlett-Packard and Logitech Corporations. All rights reserved. - - Copyright (C) 1997 TWAIN Working Group: Bell+Howell, Canon, DocuMagix, - Fujitsu, Genoa Technology, Hewlett-Packard, Kofax Imaging Products, and - Ricoh Corporation. All rights reserved. - - Copyright (C) 1998 TWAIN Working Group: Adobe Systems Incorporated, - Canon Information Systems, Eastman Kodak Company, - Fujitsu Computer Products of America, Genoa Technology, - Hewlett-Packard Company, Intel Corporation, Kofax Image Products, - JFL Peripheral Solutions Inc., Ricoh Corporation, and Xerox Corporation. - All rights reserved. - - Copyright (C) 2000 TWAIN Working Group: Adobe Systems Incorporated, - Canon Information Systems, Digimarc Corporation, Eastman Kodak Company, - Fujitsu Computer Products of America, Hewlett-Packard Company, - JFL Peripheral Solutions Inc., Ricoh Corporation, and Xerox Corporation. - All rights reserved. - - - TWAIN.h - This is the definitive include file for applications and - data sources written to the TWAIN specification. - It defines constants, data structures, messages etc. - for the public interface to TWAIN. - - Revision History: - version 1.0, March 6, 1992. TWAIN 1.0. - version 1.1, January 1993. Tech Notes 1.1 - version 1.5, June 1993. Specification Update 1.5 - Change DC to TW - Change filename from DC.H to TWAIN.H - version 1.5, July 1993. Remove spaces from country identifiers - - version 1.7, July 1997 Added Capabilities and data structure for - document imaging and digital cameras. - KHL. - version 1.7, July 1997 Inserted Borland compatibile structure packing - directives provided by Mentor. JMH - version 1.7, Aug 1997 Expanded file tabs to spaces. - NOTE: future authors should be sure to have - their editors set to automatically expand tabs - to spaces (original tab setting was 4 spaces). - version 1.7, Sept 1997 Added job control values - Added return codes - version 1.7, Sept 1997 changed definition of pRGBRESPONSE to - pTW_RGBRESPONSE - version 1.7 Aug 1998 Added missing TWEI_BARCODEROTATION values - TWBCOR_ types JMH - version 1.8 August 1998 Added new types and definitions required - for 1.8 Specification JMH - version 1.8 January 1999 Changed search mode from SRCH_ to TWBD_ as - in 1.8 Specification, added TWBT_MAXICODE JMH - version 1.8 January 1999 Removed undocumented duplicate AUTO JMH - version 1.8 March 1999 Removed undocumented 1.8 caps: - CAP_FILESYSTEM - CAP_PAPERBINDING - CAP_PASSTHRU - CAP_POWERDOWNTIME - ICAP_AUTODISCARDBLANKPAGES - * CAP_PAGEMULTIPLEACQUIRE - is CAP_REACQUIREALLOWED, - requires spec change. JMH - Added Mac structure packing modifications JMH - version 1.9 March 2000 Added new types and definations required - for 1.9 Specification MLM - version 1.9 March 2000 Added ICAP_JPEGQUALITY, TWJQ_ values, - updated TWON_PROTOCOLMINOR for Release v1.9 MN - version 1.91 August 2007 Added new types and definitions required - for 1.91 Specification MLM - version 2.0 Sept 2007 Added new types and definitions required - for 2.0 Specification FHH - version 2.0 Mar 2008 Depreciated ICAP_PIXELTYPEs TWPT_SRGB64, TWPT_BGR, - TWPT_CIELAB, TWPT_CIELUV, and TWPT_YCBCR JMW - version 2.0 Mar 2008 Added missing new 2.0 CAP_ definitions JMW - version 2.0 Dec 2008 Updated TW_INFO structure for 64bit JMW - version 2.1 Mar 2009 Added new types and definitions required - for 2.1 Specification JMW - version 2.2 Nov 2010 Added new types and definitions required - for 2.2 Specification MSM - version 2.3 Feb 2013 Added new types and definitions required - for 2.3 Specification MLM - version 2.3a Apr 2015 Errata fixes to TWCY_ANDORRA and TWCY_CUBA - version 2.4 Aug 2015 Added new types and definitions required - for 2.4 Specification MLM - version 2.4a June 2016 Added TW_INT32 and TW_UINT32 fixes for Linux, - (I just added this comment today) - version 2.4b March 2017 Missing changeset from 2.3 verion (2013/06/20) - - -\* ======================================================================== */ - -#ifndef TWAIN -#define TWAIN - -/**************************************************************************** - * TWAIN Version * - ****************************************************************************/ -#define TWON_PROTOCOLMINOR 4 /* Changed for Version 2.4 */ -#define TWON_PROTOCOLMAJOR 2 - -/**************************************************************************** - * Platform Dependent Definitions and Typedefs * - ****************************************************************************/ - -/* Microsoft C/C++ Compiler */ -#if defined(WIN32) || defined(WIN64) || defined (_WINDOWS) - #define TWH_CMP_MSC - #if defined(_WIN64) || defined(WIN64) - #define TWH_64BIT - #elif defined(WIN32) || defined(_WIN32) - #define TWH_32BIT - #endif - -/* GNU C/C++ Compiler */ -#elif defined(__GNUC__) - #define TWH_CMP_GNU - #if defined(__alpha__)\ - ||defined(__ia64__)\ - ||defined(__ppc64__)\ - ||defined(__s390x__)\ - ||defined(__x86_64__) - #define TWH_64BIT - #else - #define TWH_32BIT - #endif - - -/* Borland C/C++ Compiler */ -#elif defined(__BORLAND__) - #define TWH_CMP_BORLAND - #define TWH_32BIT -/* Unrecognized */ -#else - #error Unrecognized compiler -#endif - -/* Apple Compiler (which is GNU now) */ -#if defined(__APPLE__) - #define TWH_CMP_XCODE - #ifdef __MWERKS__ - #include - #else - #include - #endif -#endif - -/* Win32 and Win64 systems */ -#if defined(TWH_CMP_MSC) | defined(TWH_CMP_BORLAND) - typedef HANDLE TW_HANDLE; - typedef LPVOID TW_MEMREF; - typedef UINT_PTR TW_UINTPTR; - -/* MacOS/X... */ -#elif defined(TWH_CMP_XCODE) - #define PASCAL pascal - #define FAR - typedef Handle TW_HANDLE; - typedef char *TW_MEMREF; - typedef unsigned char BYTE; - - #ifdef TWH_32BIT - //32 bit GNU - typedef unsigned long TW_UINTPTR; - #else - //64 bit GNU - typedef unsigned long long TW_UINTPTR; - #endif - -/* Everything else... */ -#else - #define PASCAL - #define FAR - typedef void* TW_HANDLE; - typedef void* TW_MEMREF; - typedef unsigned char BYTE; - - #ifdef TWH_32BIT - //32 bit GNU - typedef unsigned long TW_UINTPTR; - #else - //64 bit GNU - typedef unsigned long long TW_UINTPTR; - #endif -#endif - - -/* Set the packing: this occurs before any structures are defined */ -#ifdef TWH_CMP_MSC - #pragma pack (push, before_twain) - #pragma pack (2) -#elif defined(TWH_CMP_GNU) - #if defined(__APPLE__) /* cf: Mac version of TWAIN.h */ - #pragma options align = power - #else - #pragma pack (push, before_twain) - #pragma pack (2) - #endif -#elif defined(TWH_CMP_BORLAND) - #pragma option -a2 -#endif - - -/**************************************************************************** - * Type Definitions * - ****************************************************************************/ - -/* String types. These include room for the strings and a NULL char, * - * or, on the Mac, a length byte followed by the string. * - * TW_STR255 must hold less than 256 chars so length fits in first byte. */ -#if defined(__APPLE__)/* cf: Mac version of TWAIN.h */ - typedef unsigned char TW_STR32[34], FAR *pTW_STR32; - typedef unsigned char TW_STR64[66], FAR *pTW_STR64; - typedef unsigned char TW_STR128[130], FAR *pTW_STR128; - typedef unsigned char TW_STR255[256], FAR *pTW_STR255; -#else - typedef char TW_STR32[34], FAR *pTW_STR32; - typedef char TW_STR64[66], FAR *pTW_STR64; - typedef char TW_STR128[130], FAR *pTW_STR128; - typedef char TW_STR255[256], FAR *pTW_STR255; -#endif - -/* Numeric types. */ -typedef char TW_INT8, FAR *pTW_INT8; -typedef short TW_INT16, FAR *pTW_INT16; -#if defined(_WIN32) - typedef long TW_INT32, FAR *pTW_INT32; -#else - typedef int TW_INT32, FAR *pTW_INT32; -#endif -typedef unsigned char TW_UINT8, FAR *pTW_UINT8; -typedef unsigned short TW_UINT16, FAR *pTW_UINT16; -#if defined(_WIN32) - typedef unsigned long TW_UINT32, FAR *pTW_UINT32; -#else - typedef unsigned int TW_UINT32, FAR *pTW_UINT32; -#endif -typedef unsigned short TW_BOOL, FAR *pTW_BOOL; - - -/**************************************************************************** - * Structure Definitions * - ****************************************************************************/ - -/* Fixed point structure type. */ -typedef struct { - TW_INT16 Whole; - TW_UINT16 Frac; -} TW_FIX32, FAR *pTW_FIX32; - -/* Defines a frame rectangle in ICAP_UNITS coordinates. */ -typedef struct { - TW_FIX32 Left; - TW_FIX32 Top; - TW_FIX32 Right; - TW_FIX32 Bottom; -} TW_FRAME, FAR * pTW_FRAME; - -/* Defines the parameters used for channel-specific transformation. */ -typedef struct { - TW_FIX32 StartIn; - TW_FIX32 BreakIn; - TW_FIX32 EndIn; - TW_FIX32 StartOut; - TW_FIX32 BreakOut; - TW_FIX32 EndOut; - TW_FIX32 Gamma; - TW_FIX32 SampleCount; -} TW_DECODEFUNCTION, FAR * pTW_DECODEFUNCTION; - -/* Stores a Fixed point number in two parts, a whole and a fractional part. */ -typedef struct { - TW_DECODEFUNCTION Decode[3]; - TW_FIX32 Mix[3][3]; -} TW_TRANSFORMSTAGE, FAR * pTW_TRANSFORMSTAGE; - -/* Container for array of values */ -typedef struct { - TW_UINT16 ItemType; - TW_UINT32 NumItems; - TW_UINT8 ItemList[1]; -} TW_ARRAY, FAR * pTW_ARRAY; - -/* Information about audio data */ -typedef struct { - TW_STR255 Name; - TW_UINT32 Reserved; -} TW_AUDIOINFO, FAR * pTW_AUDIOINFO; - -/* Used to register callbacks. */ -typedef struct { - TW_MEMREF CallBackProc; - #if defined(__APPLE__) /* cf: Mac version of TWAIN.h */ - TW_MEMREF RefCon; - #else - TW_UINT32 RefCon; - #endif - TW_INT16 Message; -} TW_CALLBACK, FAR * pTW_CALLBACK; - -/* Used to register callbacks. */ -typedef struct { - TW_MEMREF CallBackProc; - TW_UINTPTR RefCon; - TW_INT16 Message; -} TW_CALLBACK2, FAR * pTW_CALLBACK2; - -/* Used by application to get/set capability from/in a data source. */ -typedef struct { - TW_UINT16 Cap; - TW_UINT16 ConType; - TW_HANDLE hContainer; -} TW_CAPABILITY, FAR * pTW_CAPABILITY; - -/* Defines a CIE XYZ space tri-stimulus value. */ -typedef struct { - TW_FIX32 X; - TW_FIX32 Y; - TW_FIX32 Z; -} TW_CIEPOINT, FAR * pTW_CIEPOINT; - -/* Defines the mapping from an RGB color space device into CIE 1931 (XYZ) color space. */ -typedef struct { - TW_UINT16 ColorSpace; - TW_INT16 LowEndian; - TW_INT16 DeviceDependent; - TW_INT32 VersionNumber; - TW_TRANSFORMSTAGE StageABC; - TW_TRANSFORMSTAGE StageLMN; - TW_CIEPOINT WhitePoint; - TW_CIEPOINT BlackPoint; - TW_CIEPOINT WhitePaper; - TW_CIEPOINT BlackInk; - TW_FIX32 Samples[1]; -} TW_CIECOLOR, FAR * pTW_CIECOLOR; - -/* Allows for a data source and application to pass custom data to each other. */ -typedef struct { - TW_UINT32 InfoLength; - TW_HANDLE hData; -}TW_CUSTOMDSDATA, FAR *pTW_CUSTOMDSDATA; - -/* Provides information about the Event that was raised by the Source */ -typedef struct { - TW_UINT32 Event; - TW_STR255 DeviceName; - TW_UINT32 BatteryMinutes; - TW_INT16 BatteryPercentage; - TW_INT32 PowerSupply; - TW_FIX32 XResolution; - TW_FIX32 YResolution; - TW_UINT32 FlashUsed2; - TW_UINT32 AutomaticCapture; - TW_UINT32 TimeBeforeFirstCapture; - TW_UINT32 TimeBetweenCaptures; -} TW_DEVICEEVENT, FAR * pTW_DEVICEEVENT; - -/* This structure holds the tri-stimulus color palette information for TW_PALETTE8 structures.*/ -typedef struct { - TW_UINT8 Index; - TW_UINT8 Channel1; - TW_UINT8 Channel2; - TW_UINT8 Channel3; -} TW_ELEMENT8, FAR * pTW_ELEMENT8; - -/* Stores a group of individual values describing a capability. */ -typedef struct { - TW_UINT16 ItemType; - TW_UINT32 NumItems; - TW_UINT32 CurrentIndex; - TW_UINT32 DefaultIndex; - TW_UINT8 ItemList[1]; -} TW_ENUMERATION, FAR * pTW_ENUMERATION; - -/* Used to pass application events/messages from the application to the Source. */ -typedef struct { - TW_MEMREF pEvent; - TW_UINT16 TWMessage; -} TW_EVENT, FAR * pTW_EVENT; - -/* This structure is used to pass specific information between the data source and the application. */ -typedef struct { - TW_UINT16 InfoID; - TW_UINT16 ItemType; - TW_UINT16 NumItems; - union { - TW_UINT16 ReturnCode; - TW_UINT16 CondCode; // Deprecated, do not use - }; - TW_UINTPTR Item; -}TW_INFO, FAR* pTW_INFO; - -typedef struct { - TW_UINT32 NumInfos; - TW_INFO Info[1]; -}TW_EXTIMAGEINFO, FAR* pTW_EXTIMAGEINFO; - -/* Provides information about the currently selected device */ -typedef struct { - TW_STR255 InputName; - TW_STR255 OutputName; - TW_MEMREF Context; - union { - int Recursive; - TW_BOOL Subdirectories; - }; - union { - TW_INT32 FileType; - TW_UINT32 FileSystemType; - }; - TW_UINT32 Size; - TW_STR32 CreateTimeDate; - TW_STR32 ModifiedTimeDate; - TW_UINT32 FreeSpace; - TW_INT32 NewImageSize; - TW_UINT32 NumberOfFiles; - TW_UINT32 NumberOfSnippets; - TW_UINT32 DeviceGroupMask; - TW_INT8 Reserved[508]; -} TW_FILESYSTEM, FAR * pTW_FILESYSTEM; - -/* This structure is used by the application to specify a set of mapping values to be applied to grayscale data. */ -typedef struct { - TW_ELEMENT8 Response[1]; -} TW_GRAYRESPONSE, FAR * pTW_GRAYRESPONSE; - -/* A general way to describe the version of software that is running. */ -typedef struct { - TW_UINT16 MajorNum; - TW_UINT16 MinorNum; - TW_UINT16 Language; - TW_UINT16 Country; - TW_STR32 Info; -} TW_VERSION, FAR * pTW_VERSION; - -/* Provides identification information about a TWAIN entity.*/ -typedef struct { - #if defined(__APPLE__) /* cf: Mac version of TWAIN.h */ - TW_MEMREF Id; - #else - TW_UINT32 Id; - #endif - TW_VERSION Version; - TW_UINT16 ProtocolMajor; - TW_UINT16 ProtocolMinor; - TW_UINT32 SupportedGroups; - TW_STR32 Manufacturer; - TW_STR32 ProductFamily; - TW_STR32 ProductName; -} TW_IDENTITY, FAR * pTW_IDENTITY; - -/* Describes the "real" image data, that is, the complete image being transferred between the Source and application. */ -typedef struct { - TW_FIX32 XResolution; - TW_FIX32 YResolution; - TW_INT32 ImageWidth; - TW_INT32 ImageLength; - TW_INT16 SamplesPerPixel; - TW_INT16 BitsPerSample[8]; - TW_INT16 BitsPerPixel; - TW_BOOL Planar; - TW_INT16 PixelType; - TW_UINT16 Compression; -} TW_IMAGEINFO, FAR * pTW_IMAGEINFO; - -/* Involves information about the original size of the acquired image. */ -typedef struct { - TW_FRAME Frame; - TW_UINT32 DocumentNumber; - TW_UINT32 PageNumber; - TW_UINT32 FrameNumber; -} TW_IMAGELAYOUT, FAR * pTW_IMAGELAYOUT; - -/* Provides information for managing memory buffers. */ -typedef struct { - TW_UINT32 Flags; - TW_UINT32 Length; - TW_MEMREF TheMem; -} TW_MEMORY, FAR * pTW_MEMORY; - -/* Describes the form of the acquired data being passed from the Source to the application.*/ -typedef struct { - TW_UINT16 Compression; - TW_UINT32 BytesPerRow; - TW_UINT32 Columns; - TW_UINT32 Rows; - TW_UINT32 XOffset; - TW_UINT32 YOffset; - TW_UINT32 BytesWritten; - TW_MEMORY Memory; -} TW_IMAGEMEMXFER, FAR * pTW_IMAGEMEMXFER; - -/* Describes the information necessary to transfer a JPEG-compressed image. */ -typedef struct { - TW_UINT16 ColorSpace; - TW_UINT32 SubSampling; - TW_UINT16 NumComponents; - TW_UINT16 RestartFrequency; - TW_UINT16 QuantMap[4]; - TW_MEMORY QuantTable[4]; - TW_UINT16 HuffmanMap[4]; - TW_MEMORY HuffmanDC[2]; - TW_MEMORY HuffmanAC[2]; -} TW_JPEGCOMPRESSION, FAR * pTW_JPEGCOMPRESSION; - -/* Collects scanning metrics after returning to state 4 */ -typedef struct { - TW_UINT32 SizeOf; - TW_UINT32 ImageCount; - TW_UINT32 SheetCount; -} TW_METRICS, FAR * pTW_METRICS; - -/* Stores a single value (item) which describes a capability. */ -typedef struct { - TW_UINT16 ItemType; - TW_UINT32 Item; -} TW_ONEVALUE, FAR * pTW_ONEVALUE; - -/* This structure holds the color palette information. */ -typedef struct { - TW_UINT16 NumColors; - TW_UINT16 PaletteType; - TW_ELEMENT8 Colors[256]; -} TW_PALETTE8, FAR * pTW_PALETTE8; - -/* Used to bypass the TWAIN protocol when communicating with a device */ -typedef struct { - TW_MEMREF pCommand; - TW_UINT32 CommandBytes; - TW_INT32 Direction; - TW_MEMREF pData; - TW_UINT32 DataBytes; - TW_UINT32 DataBytesXfered; -} TW_PASSTHRU, FAR * pTW_PASSTHRU; - -/* This structure tells the application how many more complete transfers the Source currently has available. */ -typedef struct { - TW_UINT16 Count; - union { - TW_UINT32 EOJ; - TW_UINT32 Reserved; - #if defined(__APPLE__) /* cf: Mac version of TWAIN.h */ - union { - TW_UINT32 EOJ; - TW_UINT32 Reserved; - } TW_JOBCONTROL; - #endif - }; -} TW_PENDINGXFERS, FAR *pTW_PENDINGXFERS; - -/* Stores a range of individual values describing a capability. */ -typedef struct { - TW_UINT16 ItemType; - TW_UINT32 MinValue; - TW_UINT32 MaxValue; - TW_UINT32 StepSize; - TW_UINT32 DefaultValue; - TW_UINT32 CurrentValue; -} TW_RANGE, FAR * pTW_RANGE; - -/* This structure is used by the application to specify a set of mapping values to be applied to RGB color data. */ -typedef struct { - TW_ELEMENT8 Response[1]; -} TW_RGBRESPONSE, FAR * pTW_RGBRESPONSE; - -/* Describes the file format and file specification information for a transfer through a disk file. */ -typedef struct { - TW_STR255 FileName; - TW_UINT16 Format; - TW_INT16 VRefNum; -} TW_SETUPFILEXFER, FAR * pTW_SETUPFILEXFER; - -/* Provides the application information about the Source's requirements and preferences regarding allocation of transfer buffer(s). */ -typedef struct { - TW_UINT32 MinBufSize; - TW_UINT32 MaxBufSize; - TW_UINT32 Preferred; -} TW_SETUPMEMXFER, FAR * pTW_SETUPMEMXFER; - -/* Describes the status of a source. */ -typedef struct { - TW_UINT16 ConditionCode; - union { - TW_UINT16 Data; - TW_UINT16 Reserved; - }; -} TW_STATUS, FAR * pTW_STATUS; - -/* Translates the contents of Status into a localized UTF8string. */ -typedef struct { - TW_STATUS Status; - TW_UINT32 Size; - TW_HANDLE UTF8string; -} TW_STATUSUTF8, FAR * pTW_STATUSUTF8; - -typedef struct { - TW_UINT32 SizeOf; - TW_UINT16 CommunicationManager; - TW_HANDLE Send; - TW_UINT32 SendSize; - TW_HANDLE Receive; - TW_UINT32 ReceiveSize; -} TW_TWAINDIRECT, FAR * pTW_TWAINDIRECT; - -/* This structure is used to handle the user interface coordination between an application and a Source. */ -typedef struct { - TW_BOOL ShowUI; - TW_BOOL ModalUI; - TW_HANDLE hParent; -} TW_USERINTERFACE, FAR * pTW_USERINTERFACE; - - -/**************************************************************************** - * Generic Constants * - ****************************************************************************/ - -#define TWON_ARRAY 3 -#define TWON_ENUMERATION 4 -#define TWON_ONEVALUE 5 -#define TWON_RANGE 6 - -#define TWON_ICONID 962 -#define TWON_DSMID 461 -#define TWON_DSMCODEID 63 - -#define TWON_DONTCARE8 0xff -#define TWON_DONTCARE16 0xffff -#define TWON_DONTCARE32 0xffffffff - -/* Flags used in TW_MEMORY structure. */ -#define TWMF_APPOWNS 0x0001 -#define TWMF_DSMOWNS 0x0002 -#define TWMF_DSOWNS 0x0004 -#define TWMF_POINTER 0x0008 -#define TWMF_HANDLE 0x0010 - -#define TWTY_INT8 0x0000 -#define TWTY_INT16 0x0001 -#define TWTY_INT32 0x0002 - -#define TWTY_UINT8 0x0003 -#define TWTY_UINT16 0x0004 -#define TWTY_UINT32 0x0005 - -#define TWTY_BOOL 0x0006 - -#define TWTY_FIX32 0x0007 - -#define TWTY_FRAME 0x0008 - -#define TWTY_STR32 0x0009 -#define TWTY_STR64 0x000a -#define TWTY_STR128 0x000b -#define TWTY_STR255 0x000c -#define TWTY_HANDLE 0x000f - - -/**************************************************************************** - * Capability Constants * - ****************************************************************************/ - -/* CAP_ALARMS values */ -#define TWAL_ALARM 0 -#define TWAL_FEEDERERROR 1 -#define TWAL_FEEDERWARNING 2 -#define TWAL_BARCODE 3 -#define TWAL_DOUBLEFEED 4 -#define TWAL_JAM 5 -#define TWAL_PATCHCODE 6 -#define TWAL_POWER 7 -#define TWAL_SKEW 8 - -/* ICAP_AUTOSIZE values */ -#define TWAS_NONE 0 -#define TWAS_AUTO 1 -#define TWAS_CURRENT 2 - -/* TWEI_BARCODEROTATION values */ -#define TWBCOR_ROT0 0 -#define TWBCOR_ROT90 1 -#define TWBCOR_ROT180 2 -#define TWBCOR_ROT270 3 -#define TWBCOR_ROTX 4 - -/* ICAP_BARCODESEARCHMODE values */ -#define TWBD_HORZ 0 -#define TWBD_VERT 1 -#define TWBD_HORZVERT 2 -#define TWBD_VERTHORZ 3 - -/* ICAP_BITORDER values */ -#define TWBO_LSBFIRST 0 -#define TWBO_MSBFIRST 1 - -/* ICAP_AUTODISCARDBLANKPAGES values */ -#define TWBP_DISABLE -2 -#define TWBP_AUTO -1 - -/* ICAP_BITDEPTHREDUCTION values */ -#define TWBR_THRESHOLD 0 -#define TWBR_HALFTONE 1 -#define TWBR_CUSTHALFTONE 2 -#define TWBR_DIFFUSION 3 -#define TWBR_DYNAMICTHRESHOLD 4 - -/* ICAP_SUPPORTEDBARCODETYPES and TWEI_BARCODETYPE values*/ -#define TWBT_3OF9 0 -#define TWBT_2OF5INTERLEAVED 1 -#define TWBT_2OF5NONINTERLEAVED 2 -#define TWBT_CODE93 3 -#define TWBT_CODE128 4 -#define TWBT_UCC128 5 -#define TWBT_CODABAR 6 -#define TWBT_UPCA 7 -#define TWBT_UPCE 8 -#define TWBT_EAN8 9 -#define TWBT_EAN13 10 -#define TWBT_POSTNET 11 -#define TWBT_PDF417 12 -#define TWBT_2OF5INDUSTRIAL 13 -#define TWBT_2OF5MATRIX 14 -#define TWBT_2OF5DATALOGIC 15 -#define TWBT_2OF5IATA 16 -#define TWBT_3OF9FULLASCII 17 -#define TWBT_CODABARWITHSTARTSTOP 18 -#define TWBT_MAXICODE 19 -#define TWBT_QRCODE 20 - -/* ICAP_COMPRESSION values*/ -#define TWCP_NONE 0 -#define TWCP_PACKBITS 1 -#define TWCP_GROUP31D 2 -#define TWCP_GROUP31DEOL 3 -#define TWCP_GROUP32D 4 -#define TWCP_GROUP4 5 -#define TWCP_JPEG 6 -#define TWCP_LZW 7 -#define TWCP_JBIG 8 -#define TWCP_PNG 9 -#define TWCP_RLE4 10 -#define TWCP_RLE8 11 -#define TWCP_BITFIELDS 12 -#define TWCP_ZIP 13 -#define TWCP_JPEG2000 14 - -/* CAP_CAMERASIDE and TWEI_PAGESIDE values */ -#define TWCS_BOTH 0 -#define TWCS_TOP 1 -#define TWCS_BOTTOM 2 - -/* CAP_DEVICEEVENT values */ -#define TWDE_CUSTOMEVENTS 0x8000 -#define TWDE_CHECKAUTOMATICCAPTURE 0 -#define TWDE_CHECKBATTERY 1 -#define TWDE_CHECKDEVICEONLINE 2 -#define TWDE_CHECKFLASH 3 -#define TWDE_CHECKPOWERSUPPLY 4 -#define TWDE_CHECKRESOLUTION 5 -#define TWDE_DEVICEADDED 6 -#define TWDE_DEVICEOFFLINE 7 -#define TWDE_DEVICEREADY 8 -#define TWDE_DEVICEREMOVED 9 -#define TWDE_IMAGECAPTURED 10 -#define TWDE_IMAGEDELETED 11 -#define TWDE_PAPERDOUBLEFEED 12 -#define TWDE_PAPERJAM 13 -#define TWDE_LAMPFAILURE 14 -#define TWDE_POWERSAVE 15 -#define TWDE_POWERSAVENOTIFY 16 - -/* TW_PASSTHRU.Direction values. */ -#define TWDR_GET 1 -#define TWDR_SET 2 - -/* TWEI_DESKEWSTATUS values. */ -#define TWDSK_SUCCESS 0 -#define TWDSK_REPORTONLY 1 -#define TWDSK_FAIL 2 -#define TWDSK_DISABLED 3 - -/* CAP_DUPLEX values */ -#define TWDX_NONE 0 -#define TWDX_1PASSDUPLEX 1 -#define TWDX_2PASSDUPLEX 2 - -/* CAP_FEEDERALIGNMENT values */ -#define TWFA_NONE 0 -#define TWFA_LEFT 1 -#define TWFA_CENTER 2 -#define TWFA_RIGHT 3 - -/* ICAP_FEEDERTYPE values*/ -#define TWFE_GENERAL 0 -#define TWFE_PHOTO 1 - -/* ICAP_IMAGEFILEFORMAT values */ -#define TWFF_TIFF 0 -#define TWFF_PICT 1 -#define TWFF_BMP 2 -#define TWFF_XBM 3 -#define TWFF_JFIF 4 -#define TWFF_FPX 5 -#define TWFF_TIFFMULTI 6 -#define TWFF_PNG 7 -#define TWFF_SPIFF 8 -#define TWFF_EXIF 9 -#define TWFF_PDF 10 -#define TWFF_JP2 11 -#define TWFF_JPX 13 -#define TWFF_DEJAVU 14 -#define TWFF_PDFA 15 -#define TWFF_PDFA2 16 -#define TWFF_PDFRASTER 17 - -/* ICAP_FLASHUSED2 values */ -#define TWFL_NONE 0 -#define TWFL_OFF 1 -#define TWFL_ON 2 -#define TWFL_AUTO 3 -#define TWFL_REDEYE 4 - -/* CAP_FEEDERORDER values */ -#define TWFO_FIRSTPAGEFIRST 0 -#define TWFO_LASTPAGEFIRST 1 - -/* CAP_FEEDERPOCKET values*/ -#define TWFP_POCKETERROR 0 -#define TWFP_POCKET1 1 -#define TWFP_POCKET2 2 -#define TWFP_POCKET3 3 -#define TWFP_POCKET4 4 -#define TWFP_POCKET5 5 -#define TWFP_POCKET6 6 -#define TWFP_POCKET7 7 -#define TWFP_POCKET8 8 -#define TWFP_POCKET9 9 -#define TWFP_POCKET10 10 -#define TWFP_POCKET11 11 -#define TWFP_POCKET12 12 -#define TWFP_POCKET13 13 -#define TWFP_POCKET14 14 -#define TWFP_POCKET15 15 -#define TWFP_POCKET16 16 - -/* ICAP_FLIPROTATION values */ -#define TWFR_BOOK 0 -#define TWFR_FANFOLD 1 - -/* ICAP_FILTER values */ -#define TWFT_RED 0 -#define TWFT_GREEN 1 -#define TWFT_BLUE 2 -#define TWFT_NONE 3 -#define TWFT_WHITE 4 -#define TWFT_CYAN 5 -#define TWFT_MAGENTA 6 -#define TWFT_YELLOW 7 -#define TWFT_BLACK 8 - -/* TW_FILESYSTEM.FileType values */ -#define TWFY_CAMERA 0 -#define TWFY_CAMERATOP 1 -#define TWFY_CAMERABOTTOM 2 -#define TWFY_CAMERAPREVIEW 3 -#define TWFY_DOMAIN 4 -#define TWFY_HOST 5 -#define TWFY_DIRECTORY 6 -#define TWFY_IMAGE 7 -#define TWFY_UNKNOWN 8 - -/* ICAP_ICCPROFILE values */ -#define TWIC_NONE 0 -#define TWIC_LINK 1 -#define TWIC_EMBED 2 - -/* ICAP_IMAGEFILTER values */ -#define TWIF_NONE 0 -#define TWIF_AUTO 1 -#define TWIF_LOWPASS 2 -#define TWIF_BANDPASS 3 -#define TWIF_HIGHPASS 4 -#define TWIF_TEXT TWIF_BANDPASS -#define TWIF_FINELINE TWIF_HIGHPASS - -/* ICAP_IMAGEMERGE values */ -#define TWIM_NONE 0 -#define TWIM_FRONTONTOP 1 -#define TWIM_FRONTONBOTTOM 2 -#define TWIM_FRONTONLEFT 3 -#define TWIM_FRONTONRIGHT 4 - -/* CAP_JOBCONTROL values */ -#define TWJC_NONE 0 -#define TWJC_JSIC 1 -#define TWJC_JSIS 2 -#define TWJC_JSXC 3 -#define TWJC_JSXS 4 - -/* ICAP_JPEGQUALITY values */ -#define TWJQ_UNKNOWN -4 -#define TWJQ_LOW -3 -#define TWJQ_MEDIUM -2 -#define TWJQ_HIGH -1 - -/* ICAP_LIGHTPATH values */ -#define TWLP_REFLECTIVE 0 -#define TWLP_TRANSMISSIVE 1 - -/* ICAP_LIGHTSOURCE values */ -#define TWLS_RED 0 -#define TWLS_GREEN 1 -#define TWLS_BLUE 2 -#define TWLS_NONE 3 -#define TWLS_WHITE 4 -#define TWLS_UV 5 -#define TWLS_IR 6 - -/* TWEI_MAGTYPE values */ -#define TWMD_MICR 0 -#define TWMD_RAW 1 -#define TWMD_INVALID 2 - -/* ICAP_NOISEFILTER values */ -#define TWNF_NONE 0 -#define TWNF_AUTO 1 -#define TWNF_LONEPIXEL 2 -#define TWNF_MAJORITYRULE 3 - -/* ICAP_ORIENTATION values */ -#define TWOR_ROT0 0 -#define TWOR_ROT90 1 -#define TWOR_ROT180 2 -#define TWOR_ROT270 3 -#define TWOR_PORTRAIT TWOR_ROT0 -#define TWOR_LANDSCAPE TWOR_ROT270 -#define TWOR_AUTO 4 -#define TWOR_AUTOTEXT 5 -#define TWOR_AUTOPICTURE 6 - -/* ICAP_OVERSCAN values */ -#define TWOV_NONE 0 -#define TWOV_AUTO 1 -#define TWOV_TOPBOTTOM 2 -#define TWOV_LEFTRIGHT 3 -#define TWOV_ALL 4 - -/* Palette types for TW_PALETTE8 */ -#define TWPA_RGB 0 -#define TWPA_GRAY 1 -#define TWPA_CMY 2 - -/* ICAP_PLANARCHUNKY values */ -#define TWPC_CHUNKY 0 -#define TWPC_PLANAR 1 - -/* TWEI_PATCHCODE values*/ -#define TWPCH_PATCH1 0 -#define TWPCH_PATCH2 1 -#define TWPCH_PATCH3 2 -#define TWPCH_PATCH4 3 -#define TWPCH_PATCH6 4 -#define TWPCH_PATCHT 5 - -/* ICAP_PIXELFLAVOR values */ -#define TWPF_CHOCOLATE 0 -#define TWPF_VANILLA 1 - -/* CAP_PRINTERMODE values */ -#define TWPM_SINGLESTRING 0 -#define TWPM_MULTISTRING 1 -#define TWPM_COMPOUNDSTRING 2 - -/* CAP_PRINTER values */ -#define TWPR_IMPRINTERTOPBEFORE 0 -#define TWPR_IMPRINTERTOPAFTER 1 -#define TWPR_IMPRINTERBOTTOMBEFORE 2 -#define TWPR_IMPRINTERBOTTOMAFTER 3 -#define TWPR_ENDORSERTOPBEFORE 4 -#define TWPR_ENDORSERTOPAFTER 5 -#define TWPR_ENDORSERBOTTOMBEFORE 6 -#define TWPR_ENDORSERBOTTOMAFTER 7 - -/* CAP_PRINTERFONTSTYLE Added 2.3 */ -#define TWPF_NORMAL 0 -#define TWPF_BOLD 1 -#define TWPF_ITALIC 2 -#define TWPF_LARGESIZE 3 -#define TWPF_SMALLSIZE 4 - -/* CAP_PRINTERINDEXTRIGGER Added 2.3 */ -#define TWCT_PAGE 0 -#define TWCT_PATCH1 1 -#define TWCT_PATCH2 2 -#define TWCT_PATCH3 3 -#define TWCT_PATCH4 4 -#define TWCT_PATCHT 5 -#define TWCT_PATCH6 6 - -/* CAP_POWERSUPPLY values */ -#define TWPS_EXTERNAL 0 -#define TWPS_BATTERY 1 - -/* ICAP_PIXELTYPE values (PT_ means Pixel Type) */ -#define TWPT_BW 0 -#define TWPT_GRAY 1 -#define TWPT_RGB 2 -#define TWPT_PALETTE 3 -#define TWPT_CMY 4 -#define TWPT_CMYK 5 -#define TWPT_YUV 6 -#define TWPT_YUVK 7 -#define TWPT_CIEXYZ 8 -#define TWPT_LAB 9 -#define TWPT_SRGB 10 -#define TWPT_SCRGB 11 -#define TWPT_INFRARED 16 - -/* CAP_SEGMENTED values */ -#define TWSG_NONE 0 -#define TWSG_AUTO 1 -#define TWSG_MANUAL 2 - -/* ICAP_FILMTYPE values */ -#define TWFM_POSITIVE 0 -#define TWFM_NEGATIVE 1 - -/* CAP_DOUBLEFEEDDETECTION */ -#define TWDF_ULTRASONIC 0 -#define TWDF_BYLENGTH 1 -#define TWDF_INFRARED 2 - -/* CAP_DOUBLEFEEDDETECTIONSENSITIVITY */ -#define TWUS_LOW 0 -#define TWUS_MEDIUM 1 -#define TWUS_HIGH 2 - -/* CAP_DOUBLEFEEDDETECTIONRESPONSE */ -#define TWDP_STOP 0 -#define TWDP_STOPANDWAIT 1 -#define TWDP_SOUND 2 -#define TWDP_DONOTIMPRINT 3 - -/* ICAP_MIRROR values */ -#define TWMR_NONE 0 -#define TWMR_VERTICAL 1 -#define TWMR_HORIZONTAL 2 - -/* ICAP_JPEGSUBSAMPLING values */ -#define TWJS_444YCBCR 0 -#define TWJS_444RGB 1 -#define TWJS_422 2 -#define TWJS_421 3 -#define TWJS_411 4 -#define TWJS_420 5 -#define TWJS_410 6 -#define TWJS_311 7 - -/* CAP_PAPERHANDLING values */ -#define TWPH_NORMAL 0 -#define TWPH_FRAGILE 1 -#define TWPH_THICK 2 -#define TWPH_TRIFOLD 3 -#define TWPH_PHOTOGRAPH 4 - -/* CAP_INDICATORSMODE values */ -#define TWCI_INFO 0 -#define TWCI_WARNING 1 -#define TWCI_ERROR 2 -#define TWCI_WARMUP 3 - -/* ICAP_SUPPORTEDSIZES values (SS_ means Supported Sizes) */ -#define TWSS_NONE 0 -#define TWSS_A4 1 -#define TWSS_JISB5 2 -#define TWSS_USLETTER 3 -#define TWSS_USLEGAL 4 -#define TWSS_A5 5 -#define TWSS_ISOB4 6 -#define TWSS_ISOB6 7 -#define TWSS_USLEDGER 9 -#define TWSS_USEXECUTIVE 10 -#define TWSS_A3 11 -#define TWSS_ISOB3 12 -#define TWSS_A6 13 -#define TWSS_C4 14 -#define TWSS_C5 15 -#define TWSS_C6 16 -#define TWSS_4A0 17 -#define TWSS_2A0 18 -#define TWSS_A0 19 -#define TWSS_A1 20 -#define TWSS_A2 21 -#define TWSS_A7 22 -#define TWSS_A8 23 -#define TWSS_A9 24 -#define TWSS_A10 25 -#define TWSS_ISOB0 26 -#define TWSS_ISOB1 27 -#define TWSS_ISOB2 28 -#define TWSS_ISOB5 29 -#define TWSS_ISOB7 30 -#define TWSS_ISOB8 31 -#define TWSS_ISOB9 32 -#define TWSS_ISOB10 33 -#define TWSS_JISB0 34 -#define TWSS_JISB1 35 -#define TWSS_JISB2 36 -#define TWSS_JISB3 37 -#define TWSS_JISB4 38 -#define TWSS_JISB6 39 -#define TWSS_JISB7 40 -#define TWSS_JISB8 41 -#define TWSS_JISB9 42 -#define TWSS_JISB10 43 -#define TWSS_C0 44 -#define TWSS_C1 45 -#define TWSS_C2 46 -#define TWSS_C3 47 -#define TWSS_C7 48 -#define TWSS_C8 49 -#define TWSS_C9 50 -#define TWSS_C10 51 -#define TWSS_USSTATEMENT 52 -#define TWSS_BUSINESSCARD 53 -#define TWSS_MAXSIZE 54 - -/* ICAP_XFERMECH values (SX_ means Setup XFer) */ -#define TWSX_NATIVE 0 -#define TWSX_FILE 1 -#define TWSX_MEMORY 2 -#define TWSX_MEMFILE 4 - -/* ICAP_UNITS values (UN_ means UNits) */ -#define TWUN_INCHES 0 -#define TWUN_CENTIMETERS 1 -#define TWUN_PICAS 2 -#define TWUN_POINTS 3 -#define TWUN_TWIPS 4 -#define TWUN_PIXELS 5 -#define TWUN_MILLIMETERS 6 - - -/**************************************************************************** - * Country Constants * - ****************************************************************************/ - -#define TWCY_AFGHANISTAN 1001 -#define TWCY_ALGERIA 213 -#define TWCY_AMERICANSAMOA 684 -#define TWCY_ANDORRA 33 -#define TWCY_ANGOLA 1002 -#define TWCY_ANGUILLA 8090 -#define TWCY_ANTIGUA 8091 -#define TWCY_ARGENTINA 54 -#define TWCY_ARUBA 297 -#define TWCY_ASCENSIONI 247 -#define TWCY_AUSTRALIA 61 -#define TWCY_AUSTRIA 43 -#define TWCY_BAHAMAS 8092 -#define TWCY_BAHRAIN 973 -#define TWCY_BANGLADESH 880 -#define TWCY_BARBADOS 8093 -#define TWCY_BELGIUM 32 -#define TWCY_BELIZE 501 -#define TWCY_BENIN 229 -#define TWCY_BERMUDA 8094 -#define TWCY_BHUTAN 1003 -#define TWCY_BOLIVIA 591 -#define TWCY_BOTSWANA 267 -#define TWCY_BRITAIN 6 -#define TWCY_BRITVIRGINIS 8095 -#define TWCY_BRAZIL 55 -#define TWCY_BRUNEI 673 -#define TWCY_BULGARIA 359 -#define TWCY_BURKINAFASO 1004 -#define TWCY_BURMA 1005 -#define TWCY_BURUNDI 1006 -#define TWCY_CAMAROON 237 -#define TWCY_CANADA 2 -#define TWCY_CAPEVERDEIS 238 -#define TWCY_CAYMANIS 8096 -#define TWCY_CENTRALAFREP 1007 -#define TWCY_CHAD 1008 -#define TWCY_CHILE 56 -#define TWCY_CHINA 86 -#define TWCY_CHRISTMASIS 1009 -#define TWCY_COCOSIS 1009 -#define TWCY_COLOMBIA 57 -#define TWCY_COMOROS 1010 -#define TWCY_CONGO 1011 -#define TWCY_COOKIS 1012 -#define TWCY_COSTARICA 506 -#define TWCY_CUBA 5 -#define TWCY_CYPRUS 357 -#define TWCY_CZECHOSLOVAKIA 42 -#define TWCY_DENMARK 45 -#define TWCY_DJIBOUTI 1013 -#define TWCY_DOMINICA 8097 -#define TWCY_DOMINCANREP 8098 -#define TWCY_EASTERIS 1014 -#define TWCY_ECUADOR 593 -#define TWCY_EGYPT 20 -#define TWCY_ELSALVADOR 503 -#define TWCY_EQGUINEA 1015 -#define TWCY_ETHIOPIA 251 -#define TWCY_FALKLANDIS 1016 -#define TWCY_FAEROEIS 298 -#define TWCY_FIJIISLANDS 679 -#define TWCY_FINLAND 358 -#define TWCY_FRANCE 33 -#define TWCY_FRANTILLES 596 -#define TWCY_FRGUIANA 594 -#define TWCY_FRPOLYNEISA 689 -#define TWCY_FUTANAIS 1043 -#define TWCY_GABON 241 -#define TWCY_GAMBIA 220 -#define TWCY_GERMANY 49 -#define TWCY_GHANA 233 -#define TWCY_GIBRALTER 350 -#define TWCY_GREECE 30 -#define TWCY_GREENLAND 299 -#define TWCY_GRENADA 8099 -#define TWCY_GRENEDINES 8015 -#define TWCY_GUADELOUPE 590 -#define TWCY_GUAM 671 -#define TWCY_GUANTANAMOBAY 5399 -#define TWCY_GUATEMALA 502 -#define TWCY_GUINEA 224 -#define TWCY_GUINEABISSAU 1017 -#define TWCY_GUYANA 592 -#define TWCY_HAITI 509 -#define TWCY_HONDURAS 504 -#define TWCY_HONGKONG 852 -#define TWCY_HUNGARY 36 -#define TWCY_ICELAND 354 -#define TWCY_INDIA 91 -#define TWCY_INDONESIA 62 -#define TWCY_IRAN 98 -#define TWCY_IRAQ 964 -#define TWCY_IRELAND 353 -#define TWCY_ISRAEL 972 -#define TWCY_ITALY 39 -#define TWCY_IVORYCOAST 225 -#define TWCY_JAMAICA 8010 -#define TWCY_JAPAN 81 -#define TWCY_JORDAN 962 -#define TWCY_KENYA 254 -#define TWCY_KIRIBATI 1018 -#define TWCY_KOREA 82 -#define TWCY_KUWAIT 965 -#define TWCY_LAOS 1019 -#define TWCY_LEBANON 1020 -#define TWCY_LIBERIA 231 -#define TWCY_LIBYA 218 -#define TWCY_LIECHTENSTEIN 41 -#define TWCY_LUXENBOURG 352 -#define TWCY_MACAO 853 -#define TWCY_MADAGASCAR 1021 -#define TWCY_MALAWI 265 -#define TWCY_MALAYSIA 60 -#define TWCY_MALDIVES 960 -#define TWCY_MALI 1022 -#define TWCY_MALTA 356 -#define TWCY_MARSHALLIS 692 -#define TWCY_MAURITANIA 1023 -#define TWCY_MAURITIUS 230 -#define TWCY_MEXICO 3 -#define TWCY_MICRONESIA 691 -#define TWCY_MIQUELON 508 -#define TWCY_MONACO 33 -#define TWCY_MONGOLIA 1024 -#define TWCY_MONTSERRAT 8011 -#define TWCY_MOROCCO 212 -#define TWCY_MOZAMBIQUE 1025 -#define TWCY_NAMIBIA 264 -#define TWCY_NAURU 1026 -#define TWCY_NEPAL 977 -#define TWCY_NETHERLANDS 31 -#define TWCY_NETHANTILLES 599 -#define TWCY_NEVIS 8012 -#define TWCY_NEWCALEDONIA 687 -#define TWCY_NEWZEALAND 64 -#define TWCY_NICARAGUA 505 -#define TWCY_NIGER 227 -#define TWCY_NIGERIA 234 -#define TWCY_NIUE 1027 -#define TWCY_NORFOLKI 1028 -#define TWCY_NORWAY 47 -#define TWCY_OMAN 968 -#define TWCY_PAKISTAN 92 -#define TWCY_PALAU 1029 -#define TWCY_PANAMA 507 -#define TWCY_PARAGUAY 595 -#define TWCY_PERU 51 -#define TWCY_PHILLIPPINES 63 -#define TWCY_PITCAIRNIS 1030 -#define TWCY_PNEWGUINEA 675 -#define TWCY_POLAND 48 -#define TWCY_PORTUGAL 351 -#define TWCY_QATAR 974 -#define TWCY_REUNIONI 1031 -#define TWCY_ROMANIA 40 -#define TWCY_RWANDA 250 -#define TWCY_SAIPAN 670 -#define TWCY_SANMARINO 39 -#define TWCY_SAOTOME 1033 -#define TWCY_SAUDIARABIA 966 -#define TWCY_SENEGAL 221 -#define TWCY_SEYCHELLESIS 1034 -#define TWCY_SIERRALEONE 1035 -#define TWCY_SINGAPORE 65 -#define TWCY_SOLOMONIS 1036 -#define TWCY_SOMALI 1037 -#define TWCY_SOUTHAFRICA 27 -#define TWCY_SPAIN 34 -#define TWCY_SRILANKA 94 -#define TWCY_STHELENA 1032 -#define TWCY_STKITTS 8013 -#define TWCY_STLUCIA 8014 -#define TWCY_STPIERRE 508 -#define TWCY_STVINCENT 8015 -#define TWCY_SUDAN 1038 -#define TWCY_SURINAME 597 -#define TWCY_SWAZILAND 268 -#define TWCY_SWEDEN 46 -#define TWCY_SWITZERLAND 41 -#define TWCY_SYRIA 1039 -#define TWCY_TAIWAN 886 -#define TWCY_TANZANIA 255 -#define TWCY_THAILAND 66 -#define TWCY_TOBAGO 8016 -#define TWCY_TOGO 228 -#define TWCY_TONGAIS 676 -#define TWCY_TRINIDAD 8016 -#define TWCY_TUNISIA 216 -#define TWCY_TURKEY 90 -#define TWCY_TURKSCAICOS 8017 -#define TWCY_TUVALU 1040 -#define TWCY_UGANDA 256 -#define TWCY_USSR 7 -#define TWCY_UAEMIRATES 971 -#define TWCY_UNITEDKINGDOM 44 -#define TWCY_USA 1 -#define TWCY_URUGUAY 598 -#define TWCY_VANUATU 1041 -#define TWCY_VATICANCITY 39 -#define TWCY_VENEZUELA 58 -#define TWCY_WAKE 1042 -#define TWCY_WALLISIS 1043 -#define TWCY_WESTERNSAHARA 1044 -#define TWCY_WESTERNSAMOA 1045 -#define TWCY_YEMEN 1046 -#define TWCY_YUGOSLAVIA 38 -#define TWCY_ZAIRE 243 -#define TWCY_ZAMBIA 260 -#define TWCY_ZIMBABWE 263 -#define TWCY_ALBANIA 355 -#define TWCY_ARMENIA 374 -#define TWCY_AZERBAIJAN 994 -#define TWCY_BELARUS 375 -#define TWCY_BOSNIAHERZGO 387 -#define TWCY_CAMBODIA 855 -#define TWCY_CROATIA 385 -#define TWCY_CZECHREPUBLIC 420 -#define TWCY_DIEGOGARCIA 246 -#define TWCY_ERITREA 291 -#define TWCY_ESTONIA 372 -#define TWCY_GEORGIA 995 -#define TWCY_LATVIA 371 -#define TWCY_LESOTHO 266 -#define TWCY_LITHUANIA 370 -#define TWCY_MACEDONIA 389 -#define TWCY_MAYOTTEIS 269 -#define TWCY_MOLDOVA 373 -#define TWCY_MYANMAR 95 -#define TWCY_NORTHKOREA 850 -#define TWCY_PUERTORICO 787 -#define TWCY_RUSSIA 7 -#define TWCY_SERBIA 381 -#define TWCY_SLOVAKIA 421 -#define TWCY_SLOVENIA 386 -#define TWCY_SOUTHKOREA 82 -#define TWCY_UKRAINE 380 -#define TWCY_USVIRGINIS 340 -#define TWCY_VIETNAM 84 - -/**************************************************************************** - * Language Constants * - ****************************************************************************/ -#define TWLG_USERLOCALE -1 -#define TWLG_DAN 0 -#define TWLG_DUT 1 -#define TWLG_ENG 2 -#define TWLG_FCF 3 -#define TWLG_FIN 4 -#define TWLG_FRN 5 -#define TWLG_GER 6 -#define TWLG_ICE 7 -#define TWLG_ITN 8 -#define TWLG_NOR 9 -#define TWLG_POR 10 -#define TWLG_SPA 11 -#define TWLG_SWE 12 -#define TWLG_USA 13 -#define TWLG_AFRIKAANS 14 -#define TWLG_ALBANIA 15 -#define TWLG_ARABIC 16 -#define TWLG_ARABIC_ALGERIA 17 -#define TWLG_ARABIC_BAHRAIN 18 -#define TWLG_ARABIC_EGYPT 19 -#define TWLG_ARABIC_IRAQ 20 -#define TWLG_ARABIC_JORDAN 21 -#define TWLG_ARABIC_KUWAIT 22 -#define TWLG_ARABIC_LEBANON 23 -#define TWLG_ARABIC_LIBYA 24 -#define TWLG_ARABIC_MOROCCO 25 -#define TWLG_ARABIC_OMAN 26 -#define TWLG_ARABIC_QATAR 27 -#define TWLG_ARABIC_SAUDIARABIA 28 -#define TWLG_ARABIC_SYRIA 29 -#define TWLG_ARABIC_TUNISIA 30 -#define TWLG_ARABIC_UAE 31 -#define TWLG_ARABIC_YEMEN 32 -#define TWLG_BASQUE 33 -#define TWLG_BYELORUSSIAN 34 -#define TWLG_BULGARIAN 35 -#define TWLG_CATALAN 36 -#define TWLG_CHINESE 37 -#define TWLG_CHINESE_HONGKONG 38 -#define TWLG_CHINESE_PRC 39 -#define TWLG_CHINESE_SINGAPORE 40 -#define TWLG_CHINESE_SIMPLIFIED 41 -#define TWLG_CHINESE_TAIWAN 42 -#define TWLG_CHINESE_TRADITIONAL 43 -#define TWLG_CROATIA 44 -#define TWLG_CZECH 45 -#define TWLG_DANISH TWLG_DAN -#define TWLG_DUTCH TWLG_DUT -#define TWLG_DUTCH_BELGIAN 46 -#define TWLG_ENGLISH TWLG_ENG -#define TWLG_ENGLISH_AUSTRALIAN 47 -#define TWLG_ENGLISH_CANADIAN 48 -#define TWLG_ENGLISH_IRELAND 49 -#define TWLG_ENGLISH_NEWZEALAND 50 -#define TWLG_ENGLISH_SOUTHAFRICA 51 -#define TWLG_ENGLISH_UK 52 -#define TWLG_ENGLISH_USA TWLG_USA -#define TWLG_ESTONIAN 53 -#define TWLG_FAEROESE 54 -#define TWLG_FARSI 55 -#define TWLG_FINNISH TWLG_FIN -#define TWLG_FRENCH TWLG_FRN -#define TWLG_FRENCH_BELGIAN 56 -#define TWLG_FRENCH_CANADIAN TWLG_FCF -#define TWLG_FRENCH_LUXEMBOURG 57 -#define TWLG_FRENCH_SWISS 58 -#define TWLG_GERMAN TWLG_GER -#define TWLG_GERMAN_AUSTRIAN 59 -#define TWLG_GERMAN_LUXEMBOURG 60 -#define TWLG_GERMAN_LIECHTENSTEIN 61 -#define TWLG_GERMAN_SWISS 62 -#define TWLG_GREEK 63 -#define TWLG_HEBREW 64 -#define TWLG_HUNGARIAN 65 -#define TWLG_ICELANDIC TWLG_ICE -#define TWLG_INDONESIAN 66 -#define TWLG_ITALIAN TWLG_ITN -#define TWLG_ITALIAN_SWISS 67 -#define TWLG_JAPANESE 68 -#define TWLG_KOREAN 69 -#define TWLG_KOREAN_JOHAB 70 -#define TWLG_LATVIAN 71 -#define TWLG_LITHUANIAN 72 -#define TWLG_NORWEGIAN TWLG_NOR -#define TWLG_NORWEGIAN_BOKMAL 73 -#define TWLG_NORWEGIAN_NYNORSK 74 -#define TWLG_POLISH 75 -#define TWLG_PORTUGUESE TWLG_POR -#define TWLG_PORTUGUESE_BRAZIL 76 -#define TWLG_ROMANIAN 77 -#define TWLG_RUSSIAN 78 -#define TWLG_SERBIAN_LATIN 79 -#define TWLG_SLOVAK 80 -#define TWLG_SLOVENIAN 81 -#define TWLG_SPANISH TWLG_SPA -#define TWLG_SPANISH_MEXICAN 82 -#define TWLG_SPANISH_MODERN 83 -#define TWLG_SWEDISH TWLG_SWE -#define TWLG_THAI 84 -#define TWLG_TURKISH 85 -#define TWLG_UKRANIAN 86 -#define TWLG_ASSAMESE 87 -#define TWLG_BENGALI 88 -#define TWLG_BIHARI 89 -#define TWLG_BODO 90 -#define TWLG_DOGRI 91 -#define TWLG_GUJARATI 92 -#define TWLG_HARYANVI 93 -#define TWLG_HINDI 94 -#define TWLG_KANNADA 95 -#define TWLG_KASHMIRI 96 -#define TWLG_MALAYALAM 97 -#define TWLG_MARATHI 98 -#define TWLG_MARWARI 99 -#define TWLG_MEGHALAYAN 100 -#define TWLG_MIZO 101 -#define TWLG_NAGA 102 -#define TWLG_ORISSI 103 -#define TWLG_PUNJABI 104 -#define TWLG_PUSHTU 105 -#define TWLG_SERBIAN_CYRILLIC 106 -#define TWLG_SIKKIMI 107 -#define TWLG_SWEDISH_FINLAND 108 -#define TWLG_TAMIL 109 -#define TWLG_TELUGU 110 -#define TWLG_TRIPURI 111 -#define TWLG_URDU 112 -#define TWLG_VIETNAMESE 113 - - -/**************************************************************************** - * Data Groups * - ****************************************************************************/ -#define DG_CONTROL 0x0001L -#define DG_IMAGE 0x0002L -#define DG_AUDIO 0x0004L - -/* More Data Functionality may be added in the future. - * These are for items that need to be determined before DS is opened. - * NOTE: Supported Functionality constants must be powers of 2 as they are - * used as bitflags when Application asks DSM to present a list of DSs. - * to support backward capability the App and DS will not use the fields - */ -#define DF_DSM2 0x10000000L -#define DF_APP2 0x20000000L - -#define DF_DS2 0x40000000L - -#define DG_MASK 0xFFFFL - -/**************************************************************************** - * * - ****************************************************************************/ -#define DAT_NULL 0x0000 -#define DAT_CUSTOMBASE 0x8000 - -/* Data Argument Types for the DG_CONTROL Data Group. */ -#define DAT_CAPABILITY 0x0001 -#define DAT_EVENT 0x0002 -#define DAT_IDENTITY 0x0003 -#define DAT_PARENT 0x0004 -#define DAT_PENDINGXFERS 0x0005 -#define DAT_SETUPMEMXFER 0x0006 -#define DAT_SETUPFILEXFER 0x0007 -#define DAT_STATUS 0x0008 -#define DAT_USERINTERFACE 0x0009 -#define DAT_XFERGROUP 0x000a -#define DAT_CUSTOMDSDATA 0x000c -#define DAT_DEVICEEVENT 0x000d -#define DAT_FILESYSTEM 0x000e -#define DAT_PASSTHRU 0x000f -#define DAT_CALLBACK 0x0010 -#define DAT_STATUSUTF8 0x0011 -#define DAT_CALLBACK2 0x0012 -#define DAT_METRICS 0x0013 -#define DAT_TWAINDIRECT 0x0014 - -/* Data Argument Types for the DG_IMAGE Data Group. */ -#define DAT_IMAGEINFO 0x0101 -#define DAT_IMAGELAYOUT 0x0102 -#define DAT_IMAGEMEMXFER 0x0103 -#define DAT_IMAGENATIVEXFER 0x0104 -#define DAT_IMAGEFILEXFER 0x0105 -#define DAT_CIECOLOR 0x0106 -#define DAT_GRAYRESPONSE 0x0107 -#define DAT_RGBRESPONSE 0x0108 -#define DAT_JPEGCOMPRESSION 0x0109 -#define DAT_PALETTE8 0x010a -#define DAT_EXTIMAGEINFO 0x010b -#define DAT_FILTER 0x010c - -/* Data Argument Types for the DG_AUDIO Data Group. */ -#define DAT_AUDIOFILEXFER 0x0201 -#define DAT_AUDIOINFO 0x0202 -#define DAT_AUDIONATIVEXFER 0x0203 - -/* misplaced */ -#define DAT_ICCPROFILE 0x0401 -#define DAT_IMAGEMEMFILEXFER 0x0402 -#define DAT_ENTRYPOINT 0x0403 - - -/**************************************************************************** - * Messages * - ****************************************************************************/ - -/* All message constants are unique. - * Messages are grouped according to which DATs they are used with.*/ - -#define MSG_NULL 0x0000 -#define MSG_CUSTOMBASE 0x8000 - -/* Generic messages may be used with any of several DATs. */ -#define MSG_GET 0x0001 -#define MSG_GETCURRENT 0x0002 -#define MSG_GETDEFAULT 0x0003 -#define MSG_GETFIRST 0x0004 -#define MSG_GETNEXT 0x0005 -#define MSG_SET 0x0006 -#define MSG_RESET 0x0007 -#define MSG_QUERYSUPPORT 0x0008 -#define MSG_GETHELP 0x0009 -#define MSG_GETLABEL 0x000a -#define MSG_GETLABELENUM 0x000b -#define MSG_SETCONSTRAINT 0x000c - -/* Messages used with DAT_NULL */ -#define MSG_XFERREADY 0x0101 -#define MSG_CLOSEDSREQ 0x0102 -#define MSG_CLOSEDSOK 0x0103 -#define MSG_DEVICEEVENT 0X0104 - -/* Messages used with a pointer to DAT_PARENT data */ -#define MSG_OPENDSM 0x0301 -#define MSG_CLOSEDSM 0x0302 - -/* Messages used with a pointer to a DAT_IDENTITY structure */ -#define MSG_OPENDS 0x0401 -#define MSG_CLOSEDS 0x0402 -#define MSG_USERSELECT 0x0403 - -/* Messages used with a pointer to a DAT_USERINTERFACE structure */ -#define MSG_DISABLEDS 0x0501 -#define MSG_ENABLEDS 0x0502 -#define MSG_ENABLEDSUIONLY 0x0503 - -/* Messages used with a pointer to a DAT_EVENT structure */ -#define MSG_PROCESSEVENT 0x0601 - -/* Messages used with a pointer to a DAT_PENDINGXFERS structure */ -#define MSG_ENDXFER 0x0701 -#define MSG_STOPFEEDER 0x0702 - -/* Messages used with a pointer to a DAT_FILESYSTEM structure */ -#define MSG_CHANGEDIRECTORY 0x0801 -#define MSG_CREATEDIRECTORY 0x0802 -#define MSG_DELETE 0x0803 -#define MSG_FORMATMEDIA 0x0804 -#define MSG_GETCLOSE 0x0805 -#define MSG_GETFIRSTFILE 0x0806 -#define MSG_GETINFO 0x0807 -#define MSG_GETNEXTFILE 0x0808 -#define MSG_RENAME 0x0809 -#define MSG_COPY 0x080A -#define MSG_AUTOMATICCAPTUREDIRECTORY 0x080B - -/* Messages used with a pointer to a DAT_PASSTHRU structure */ -#define MSG_PASSTHRU 0x0901 - -/* used with DAT_CALLBACK */ -#define MSG_REGISTER_CALLBACK 0x0902 - -/* used with DAT_CAPABILITY */ -#define MSG_RESETALL 0x0A01 - -/* used with DAT_TWAINDIRECT */ -#define MSG_SETTASK 0x0B01 - -/**************************************************************************** - * Capabilities * - ****************************************************************************/ - -#define CAP_CUSTOMBASE 0x8000 /* Base of custom capabilities */ - -/* all data sources are REQUIRED to support these caps */ -#define CAP_XFERCOUNT 0x0001 - -/* image data sources are REQUIRED to support these caps */ -#define ICAP_COMPRESSION 0x0100 -#define ICAP_PIXELTYPE 0x0101 -#define ICAP_UNITS 0x0102 -#define ICAP_XFERMECH 0x0103 - -/* all data sources MAY support these caps */ -#define CAP_AUTHOR 0x1000 -#define CAP_CAPTION 0x1001 -#define CAP_FEEDERENABLED 0x1002 -#define CAP_FEEDERLOADED 0x1003 -#define CAP_TIMEDATE 0x1004 -#define CAP_SUPPORTEDCAPS 0x1005 -#define CAP_EXTENDEDCAPS 0x1006 -#define CAP_AUTOFEED 0x1007 -#define CAP_CLEARPAGE 0x1008 -#define CAP_FEEDPAGE 0x1009 -#define CAP_REWINDPAGE 0x100a -#define CAP_INDICATORS 0x100b -#define CAP_PAPERDETECTABLE 0x100d -#define CAP_UICONTROLLABLE 0x100e -#define CAP_DEVICEONLINE 0x100f -#define CAP_AUTOSCAN 0x1010 -#define CAP_THUMBNAILSENABLED 0x1011 -#define CAP_DUPLEX 0x1012 -#define CAP_DUPLEXENABLED 0x1013 -#define CAP_ENABLEDSUIONLY 0x1014 -#define CAP_CUSTOMDSDATA 0x1015 -#define CAP_ENDORSER 0x1016 -#define CAP_JOBCONTROL 0x1017 -#define CAP_ALARMS 0x1018 -#define CAP_ALARMVOLUME 0x1019 -#define CAP_AUTOMATICCAPTURE 0x101a -#define CAP_TIMEBEFOREFIRSTCAPTURE 0x101b -#define CAP_TIMEBETWEENCAPTURES 0x101c -#define CAP_MAXBATCHBUFFERS 0x101e -#define CAP_DEVICETIMEDATE 0x101f -#define CAP_POWERSUPPLY 0x1020 -#define CAP_CAMERAPREVIEWUI 0x1021 -#define CAP_DEVICEEVENT 0x1022 -#define CAP_SERIALNUMBER 0x1024 -#define CAP_PRINTER 0x1026 -#define CAP_PRINTERENABLED 0x1027 -#define CAP_PRINTERINDEX 0x1028 -#define CAP_PRINTERMODE 0x1029 -#define CAP_PRINTERSTRING 0x102a -#define CAP_PRINTERSUFFIX 0x102b -#define CAP_LANGUAGE 0x102c -#define CAP_FEEDERALIGNMENT 0x102d -#define CAP_FEEDERORDER 0x102e -#define CAP_REACQUIREALLOWED 0x1030 -#define CAP_BATTERYMINUTES 0x1032 -#define CAP_BATTERYPERCENTAGE 0x1033 -#define CAP_CAMERASIDE 0x1034 -#define CAP_SEGMENTED 0x1035 -#define CAP_CAMERAENABLED 0x1036 -#define CAP_CAMERAORDER 0x1037 -#define CAP_MICRENABLED 0x1038 -#define CAP_FEEDERPREP 0x1039 -#define CAP_FEEDERPOCKET 0x103a -#define CAP_AUTOMATICSENSEMEDIUM 0x103b -#define CAP_CUSTOMINTERFACEGUID 0x103c -#define CAP_SUPPORTEDCAPSSEGMENTUNIQUE 0x103d -#define CAP_SUPPORTEDDATS 0x103e -#define CAP_DOUBLEFEEDDETECTION 0x103f -#define CAP_DOUBLEFEEDDETECTIONLENGTH 0x1040 -#define CAP_DOUBLEFEEDDETECTIONSENSITIVITY 0x1041 -#define CAP_DOUBLEFEEDDETECTIONRESPONSE 0x1042 -#define CAP_PAPERHANDLING 0x1043 -#define CAP_INDICATORSMODE 0x1044 -#define CAP_PRINTERVERTICALOFFSET 0x1045 -#define CAP_POWERSAVETIME 0x1046 -#define CAP_PRINTERCHARROTATION 0x1047 -#define CAP_PRINTERFONTSTYLE 0x1048 -#define CAP_PRINTERINDEXLEADCHAR 0x1049 -#define CAP_PRINTERINDEXMAXVALUE 0x104A -#define CAP_PRINTERINDEXNUMDIGITS 0x104B -#define CAP_PRINTERINDEXSTEP 0x104C -#define CAP_PRINTERINDEXTRIGGER 0x104D -#define CAP_PRINTERSTRINGPREVIEW 0x104E -#define CAP_SHEETCOUNT 0x104F - - - -/* image data sources MAY support these caps */ -#define ICAP_AUTOBRIGHT 0x1100 -#define ICAP_BRIGHTNESS 0x1101 -#define ICAP_CONTRAST 0x1103 -#define ICAP_CUSTHALFTONE 0x1104 -#define ICAP_EXPOSURETIME 0x1105 -#define ICAP_FILTER 0x1106 -#define ICAP_FLASHUSED 0x1107 -#define ICAP_GAMMA 0x1108 -#define ICAP_HALFTONES 0x1109 -#define ICAP_HIGHLIGHT 0x110a -#define ICAP_IMAGEFILEFORMAT 0x110c -#define ICAP_LAMPSTATE 0x110d -#define ICAP_LIGHTSOURCE 0x110e -#define ICAP_ORIENTATION 0x1110 -#define ICAP_PHYSICALWIDTH 0x1111 -#define ICAP_PHYSICALHEIGHT 0x1112 -#define ICAP_SHADOW 0x1113 -#define ICAP_FRAMES 0x1114 -#define ICAP_XNATIVERESOLUTION 0x1116 -#define ICAP_YNATIVERESOLUTION 0x1117 -#define ICAP_XRESOLUTION 0x1118 -#define ICAP_YRESOLUTION 0x1119 -#define ICAP_MAXFRAMES 0x111a -#define ICAP_TILES 0x111b -#define ICAP_BITORDER 0x111c -#define ICAP_CCITTKFACTOR 0x111d -#define ICAP_LIGHTPATH 0x111e -#define ICAP_PIXELFLAVOR 0x111f -#define ICAP_PLANARCHUNKY 0x1120 -#define ICAP_ROTATION 0x1121 -#define ICAP_SUPPORTEDSIZES 0x1122 -#define ICAP_THRESHOLD 0x1123 -#define ICAP_XSCALING 0x1124 -#define ICAP_YSCALING 0x1125 -#define ICAP_BITORDERCODES 0x1126 -#define ICAP_PIXELFLAVORCODES 0x1127 -#define ICAP_JPEGPIXELTYPE 0x1128 -#define ICAP_TIMEFILL 0x112a -#define ICAP_BITDEPTH 0x112b -#define ICAP_BITDEPTHREDUCTION 0x112c -#define ICAP_UNDEFINEDIMAGESIZE 0x112d -#define ICAP_IMAGEDATASET 0x112e -#define ICAP_EXTIMAGEINFO 0x112f -#define ICAP_MINIMUMHEIGHT 0x1130 -#define ICAP_MINIMUMWIDTH 0x1131 -#define ICAP_AUTODISCARDBLANKPAGES 0x1134 -#define ICAP_FLIPROTATION 0x1136 -#define ICAP_BARCODEDETECTIONENABLED 0x1137 -#define ICAP_SUPPORTEDBARCODETYPES 0x1138 -#define ICAP_BARCODEMAXSEARCHPRIORITIES 0x1139 -#define ICAP_BARCODESEARCHPRIORITIES 0x113a -#define ICAP_BARCODESEARCHMODE 0x113b -#define ICAP_BARCODEMAXRETRIES 0x113c -#define ICAP_BARCODETIMEOUT 0x113d -#define ICAP_ZOOMFACTOR 0x113e -#define ICAP_PATCHCODEDETECTIONENABLED 0x113f -#define ICAP_SUPPORTEDPATCHCODETYPES 0x1140 -#define ICAP_PATCHCODEMAXSEARCHPRIORITIES 0x1141 -#define ICAP_PATCHCODESEARCHPRIORITIES 0x1142 -#define ICAP_PATCHCODESEARCHMODE 0x1143 -#define ICAP_PATCHCODEMAXRETRIES 0x1144 -#define ICAP_PATCHCODETIMEOUT 0x1145 -#define ICAP_FLASHUSED2 0x1146 -#define ICAP_IMAGEFILTER 0x1147 -#define ICAP_NOISEFILTER 0x1148 -#define ICAP_OVERSCAN 0x1149 -#define ICAP_AUTOMATICBORDERDETECTION 0x1150 -#define ICAP_AUTOMATICDESKEW 0x1151 -#define ICAP_AUTOMATICROTATE 0x1152 -#define ICAP_JPEGQUALITY 0x1153 -#define ICAP_FEEDERTYPE 0x1154 -#define ICAP_ICCPROFILE 0x1155 -#define ICAP_AUTOSIZE 0x1156 -#define ICAP_AUTOMATICCROPUSESFRAME 0x1157 -#define ICAP_AUTOMATICLENGTHDETECTION 0x1158 -#define ICAP_AUTOMATICCOLORENABLED 0x1159 -#define ICAP_AUTOMATICCOLORNONCOLORPIXELTYPE 0x115a -#define ICAP_COLORMANAGEMENTENABLED 0x115b -#define ICAP_IMAGEMERGE 0x115c -#define ICAP_IMAGEMERGEHEIGHTTHRESHOLD 0x115d -#define ICAP_SUPPORTEDEXTIMAGEINFO 0x115e -#define ICAP_FILMTYPE 0x115f -#define ICAP_MIRROR 0x1160 -#define ICAP_JPEGSUBSAMPLING 0x1161 - -/* image data sources MAY support these audio caps */ -#define ACAP_XFERMECH 0x1202 - - -/*************************************************************************** - * Extended Image Info Attributes section Added 1.7 * - ***************************************************************************/ - -#define TWEI_BARCODEX 0x1200 -#define TWEI_BARCODEY 0x1201 -#define TWEI_BARCODETEXT 0x1202 -#define TWEI_BARCODETYPE 0x1203 -#define TWEI_DESHADETOP 0x1204 -#define TWEI_DESHADELEFT 0x1205 -#define TWEI_DESHADEHEIGHT 0x1206 -#define TWEI_DESHADEWIDTH 0x1207 -#define TWEI_DESHADESIZE 0x1208 -#define TWEI_SPECKLESREMOVED 0x1209 -#define TWEI_HORZLINEXCOORD 0x120A -#define TWEI_HORZLINEYCOORD 0x120B -#define TWEI_HORZLINELENGTH 0x120C -#define TWEI_HORZLINETHICKNESS 0x120D -#define TWEI_VERTLINEXCOORD 0x120E -#define TWEI_VERTLINEYCOORD 0x120F -#define TWEI_VERTLINELENGTH 0x1210 -#define TWEI_VERTLINETHICKNESS 0x1211 -#define TWEI_PATCHCODE 0x1212 -#define TWEI_ENDORSEDTEXT 0x1213 -#define TWEI_FORMCONFIDENCE 0x1214 -#define TWEI_FORMTEMPLATEMATCH 0x1215 -#define TWEI_FORMTEMPLATEPAGEMATCH 0x1216 -#define TWEI_FORMHORZDOCOFFSET 0x1217 -#define TWEI_FORMVERTDOCOFFSET 0x1218 -#define TWEI_BARCODECOUNT 0x1219 -#define TWEI_BARCODECONFIDENCE 0x121A -#define TWEI_BARCODEROTATION 0x121B -#define TWEI_BARCODETEXTLENGTH 0x121C -#define TWEI_DESHADECOUNT 0x121D -#define TWEI_DESHADEBLACKCOUNTOLD 0x121E -#define TWEI_DESHADEBLACKCOUNTNEW 0x121F -#define TWEI_DESHADEBLACKRLMIN 0x1220 -#define TWEI_DESHADEBLACKRLMAX 0x1221 -#define TWEI_DESHADEWHITECOUNTOLD 0x1222 -#define TWEI_DESHADEWHITECOUNTNEW 0x1223 -#define TWEI_DESHADEWHITERLMIN 0x1224 -#define TWEI_DESHADEWHITERLAVE 0x1225 -#define TWEI_DESHADEWHITERLMAX 0x1226 -#define TWEI_BLACKSPECKLESREMOVED 0x1227 -#define TWEI_WHITESPECKLESREMOVED 0x1228 -#define TWEI_HORZLINECOUNT 0x1229 -#define TWEI_VERTLINECOUNT 0x122A -#define TWEI_DESKEWSTATUS 0x122B -#define TWEI_SKEWORIGINALANGLE 0x122C -#define TWEI_SKEWFINALANGLE 0x122D -#define TWEI_SKEWCONFIDENCE 0x122E -#define TWEI_SKEWWINDOWX1 0x122F -#define TWEI_SKEWWINDOWY1 0x1230 -#define TWEI_SKEWWINDOWX2 0x1231 -#define TWEI_SKEWWINDOWY2 0x1232 -#define TWEI_SKEWWINDOWX3 0x1233 -#define TWEI_SKEWWINDOWY3 0x1234 -#define TWEI_SKEWWINDOWX4 0x1235 -#define TWEI_SKEWWINDOWY4 0x1236 -#define TWEI_BOOKNAME 0x1238 -#define TWEI_CHAPTERNUMBER 0x1239 -#define TWEI_DOCUMENTNUMBER 0x123A -#define TWEI_PAGENUMBER 0x123B -#define TWEI_CAMERA 0x123C -#define TWEI_FRAMENUMBER 0x123D -#define TWEI_FRAME 0x123E -#define TWEI_PIXELFLAVOR 0x123F -#define TWEI_ICCPROFILE 0x1240 -#define TWEI_LASTSEGMENT 0x1241 -#define TWEI_SEGMENTNUMBER 0x1242 -#define TWEI_MAGDATA 0x1243 -#define TWEI_MAGTYPE 0x1244 -#define TWEI_PAGESIDE 0x1245 -#define TWEI_FILESYSTEMSOURCE 0x1246 -#define TWEI_IMAGEMERGED 0x1247 -#define TWEI_MAGDATALENGTH 0x1248 -#define TWEI_PAPERCOUNT 0x1249 -#define TWEI_PRINTERTEXT 0x124A -#define TWEI_TWAINDIRECTMETADATA 0x124B - -#define TWEJ_NONE 0x0000 -#define TWEJ_MIDSEPARATOR 0x0001 -#define TWEJ_PATCH1 0x0002 -#define TWEJ_PATCH2 0x0003 -#define TWEJ_PATCH3 0x0004 -#define TWEJ_PATCH4 0x0005 -#define TWEJ_PATCH6 0x0006 -#define TWEJ_PATCHT 0x0007 - - -/*************************************************************************** - * Return Codes and Condition Codes section * - ***************************************************************************/ - -#define TWRC_CUSTOMBASE 0x8000 - -#define TWRC_SUCCESS 0 -#define TWRC_FAILURE 1 -#define TWRC_CHECKSTATUS 2 -#define TWRC_CANCEL 3 -#define TWRC_DSEVENT 4 -#define TWRC_NOTDSEVENT 5 -#define TWRC_XFERDONE 6 -#define TWRC_ENDOFLIST 7 -#define TWRC_INFONOTSUPPORTED 8 -#define TWRC_DATANOTAVAILABLE 9 -#define TWRC_BUSY 10 -#define TWRC_SCANNERLOCKED 11 - -/* Condition Codes: Application gets these by doing DG_CONTROL DAT_STATUS MSG_GET. */ -#define TWCC_CUSTOMBASE 0x8000 - -#define TWCC_SUCCESS 0 -#define TWCC_BUMMER 1 -#define TWCC_LOWMEMORY 2 -#define TWCC_NODS 3 -#define TWCC_MAXCONNECTIONS 4 -#define TWCC_OPERATIONERROR 5 -#define TWCC_BADCAP 6 -#define TWCC_BADPROTOCOL 9 -#define TWCC_BADVALUE 10 -#define TWCC_SEQERROR 11 -#define TWCC_BADDEST 12 -#define TWCC_CAPUNSUPPORTED 13 -#define TWCC_CAPBADOPERATION 14 -#define TWCC_CAPSEQERROR 15 -#define TWCC_DENIED 16 -#define TWCC_FILEEXISTS 17 -#define TWCC_FILENOTFOUND 18 -#define TWCC_NOTEMPTY 19 -#define TWCC_PAPERJAM 20 -#define TWCC_PAPERDOUBLEFEED 21 -#define TWCC_FILEWRITEERROR 22 -#define TWCC_CHECKDEVICEONLINE 23 -#define TWCC_INTERLOCK 24 -#define TWCC_DAMAGEDCORNER 25 -#define TWCC_FOCUSERROR 26 -#define TWCC_DOCTOOLIGHT 27 -#define TWCC_DOCTOODARK 28 -#define TWCC_NOMEDIA 29 - -/* bit patterns: for query the operation that are supported by the data source on a capability */ -/* Application gets these through DG_CONTROL/DAT_CAPABILITY/MSG_QUERYSUPPORT */ -#define TWQC_GET 0x0001 -#define TWQC_SET 0x0002 -#define TWQC_GETDEFAULT 0x0004 -#define TWQC_GETCURRENT 0x0008 -#define TWQC_RESET 0x0010 -#define TWQC_SETCONSTRAINT 0x0020 -#define TWQC_GETHELP 0x0100 -#define TWQC_GETLABEL 0x0200 -#define TWQC_GETLABELENUM 0x0400 - -/**************************************************************************** - * Depreciated Items * - ****************************************************************************/ -#if defined(WIN32) || defined(WIN64) - #define TW_HUGE -#elif !defined(TWH_CMP_GNU) - #define TW_HUGE huge -#else - #define TW_HUGE -#endif - -typedef BYTE TW_HUGE * HPBYTE; -typedef void TW_HUGE * HPVOID; - -typedef unsigned char TW_STR1024[1026], FAR *pTW_STR1026, FAR *pTW_STR1024; -typedef wchar_t TW_UNI512[512], FAR *pTW_UNI512; - -#define TWTY_STR1024 0x000d -#define TWTY_UNI512 0x000e - -#define TWFF_JPN 12 - -#define DAT_TWUNKIDENTITY 0x000b -#define DAT_SETUPFILEXFER2 0x0301 - -#define CAP_CLEARBUFFERS 0x101d -#define CAP_SUPPORTEDCAPSEXT 0x100c -#define CAP_FILESYSTEM //0x???? -#define CAP_PAGEMULTIPLEACQUIRE 0x1023 -#define CAP_PAPERBINDING 0x102f -#define CAP_PASSTHRU 0x1031 -#define CAP_POWERDOWNTIME 0x1034 -#define ACAP_AUDIOFILEFORMAT 0x1201 - -#define MSG_CHECKSTATUS 0x0201 - -#define MSG_INVOKE_CALLBACK 0x0903 /* Mac Only, deprecated - use DAT_NULL and MSG_xxx instead */ - -#define TWQC_CONSTRAINABLE 0x0040 - -#define TWSX_FILE2 3 - -/* CAP_FILESYSTEM values (FS_ means file system) */ -#define TWFS_FILESYSTEM 0 -#define TWFS_RECURSIVEDELETE 1 - -/* ICAP_PIXELTYPE values (PT_ means Pixel Type) */ -#define TWPT_SRGB64 11 -#define TWPT_BGR 12 -#define TWPT_CIELAB 13 -#define TWPT_CIELUV 14 -#define TWPT_YCBCR 15 - -/* ICAP_SUPPORTEDSIZES values (SS_ means Supported Sizes) */ -#define TWSS_B 8 -#define TWSS_A4LETTER TWSS_A4 -#define TWSS_B3 TWSS_ISOB3 -#define TWSS_B4 TWSS_ISOB4 -#define TWSS_B6 TWSS_ISOB6 -#define TWSS_B5LETTER TWSS_JISB5 - -/* ACAP_AUDIOFILEFORMAT values (AF_ means audio format). Added 1.8 */ -#define TWAF_WAV 0 -#define TWAF_AIFF 1 -#define TWAF_AU 3 -#define TWAF_SND 4 - -/* CAP_CLEARBUFFERS values */ -#define TWCB_AUTO 0 -#define TWCB_CLEAR 1 -#define TWCB_NOCLEAR 2 - -/* DAT_SETUPFILEXFER2. Sets up DS to application data transfer via a file. Added 1.9 */ -typedef struct { - TW_MEMREF FileName; - TW_UINT16 FileNameType; - TW_UINT16 Format; - TW_INT16 VRefNum; - TW_UINT32 parID; -} TW_SETUPFILEXFER2, FAR * pTW_SETUPFILEXFER2; - -/* DAT_TWUNKIDENTITY. Provides DS identity and 'other' information necessary */ -/* across thunk link. */ -typedef struct { - TW_IDENTITY identity; - TW_STR255 dsPath; -} TW_TWUNKIDENTITY, FAR * pTW_TWUNKIDENTITY; - -/* Provides DS_Entry parameters over thunk link. */ -typedef struct -{ - TW_INT8 destFlag; - TW_IDENTITY dest; - TW_INT32 dataGroup; - TW_INT16 dataArgType; - TW_INT16 message; - TW_INT32 pDataSize; - // TW_MEMREF pData; -} TW_TWUNKDSENTRYPARAMS, FAR * pTW_TWUNKDSENTRYPARAMS; - -/* Provides DS_Entry results over thunk link. */ -typedef struct -{ - TW_UINT16 returnCode; - TW_UINT16 conditionCode; - TW_INT32 pDataSize; - // TW_MEMREF pData; -} TW_TWUNKDSENTRYRETURN, FAR * pTW_TWUNKDSENTRYRETURN; - -typedef struct -{ - TW_UINT16 Cap; - TW_UINT16 Properties; -} TW_CAPEXT, FAR * pTW_CAPEXT; - -/* DAT_SETUPAUDIOFILEXFER, information required to setup an audio file transfer */ -typedef struct { - TW_STR255 FileName; /* full path target file */ - TW_UINT16 Format; /* one of TWAF_xxxx */ - TW_INT16 VRefNum; -} TW_SETUPAUDIOFILEXFER, FAR * pTW_SETUPAUDIOFILEXFER; - - -/**************************************************************************** - * Entry Points * - ****************************************************************************/ - -/********************************************************************** - * Function: DSM_Entry, the only entry point into the Data Source Manager. - ********************************************************************/ -#ifdef TWH_CMP_MSC - #define TW_CALLINGSTYLE PASCAL -#else - #define TW_CALLINGSTYLE -#endif - -/* Don't mangle the name "DSM_Entry" if we're compiling in C++! */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -TW_UINT16 TW_CALLINGSTYLE DSM_Entry( pTW_IDENTITY pOrigin, - pTW_IDENTITY pDest, - TW_UINT32 DG, - TW_UINT16 DAT, - TW_UINT16 MSG, - TW_MEMREF pData); - -typedef TW_UINT16 (TW_CALLINGSTYLE *DSMENTRYPROC)(pTW_IDENTITY pOrigin, - pTW_IDENTITY pDest, - TW_UINT32 DG, - TW_UINT16 DAT, - TW_UINT16 MSG, - TW_MEMREF pData); -#ifdef __cplusplus -} -#endif /* cplusplus */ - - -/********************************************************************** - * Function: DS_Entry, the entry point provided by a Data Source. - ********************************************************************/ -/* Don't mangle the name "DS_Entry" if we're compiling in C++! */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -TW_UINT16 TW_CALLINGSTYLE DS_Entry(pTW_IDENTITY pOrigin, - TW_UINT32 DG, - TW_UINT16 DAT, - TW_UINT16 MSG, - TW_MEMREF pData); - -typedef TW_UINT16 (FAR PASCAL *DSENTRYPROC)(pTW_IDENTITY pOrigin, - TW_UINT32 DG, - TW_UINT16 DAT, - TW_UINT16 MSG, - TW_MEMREF pData); - -TW_UINT16 TW_CALLINGSTYLE TWAIN_Callback( pTW_IDENTITY pOrigin, - pTW_IDENTITY pDest, - TW_UINT32 DG, - TW_UINT16 DAT, - TW_UINT16 MSG, - TW_MEMREF pData); -typedef TW_UINT16 (TW_CALLINGSTYLE *TWAINCALLBACKPROC)(pTW_IDENTITY pOrigin, - pTW_IDENTITY pDest, - TW_UINT32 DG, - TW_UINT16 DAT, - TW_UINT16 MSG, - TW_MEMREF pData); - -TW_HANDLE TW_CALLINGSTYLE DSM_MemAllocate (TW_UINT32); -typedef TW_HANDLE (TW_CALLINGSTYLE *DSM_MEMALLOCATE)(TW_UINT32 _size); - -void TW_CALLINGSTYLE DSM_MemFree (TW_HANDLE); -typedef void (TW_CALLINGSTYLE *DSM_MEMFREE)(TW_HANDLE _handle); - -TW_MEMREF TW_CALLINGSTYLE DSM_MemLock (TW_HANDLE); -typedef TW_MEMREF (TW_CALLINGSTYLE *DSM_MEMLOCK)(TW_HANDLE _handle); - -void TW_CALLINGSTYLE DSM_MemUnlock (TW_HANDLE); -typedef void (TW_CALLINGSTYLE *DSM_MEMUNLOCK)(TW_HANDLE _handle); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -/* DAT_ENTRYPOINT. returns essential entry points. */ -typedef struct { - TW_UINT32 Size; - DSMENTRYPROC DSM_Entry; - DSM_MEMALLOCATE DSM_MemAllocate; - DSM_MEMFREE DSM_MemFree; - DSM_MEMLOCK DSM_MemLock; - DSM_MEMUNLOCK DSM_MemUnlock; -} TW_ENTRYPOINT, FAR * pTW_ENTRYPOINT; - -/* DAT_FILTER*/ -typedef struct { - TW_UINT32 Size; - TW_UINT32 HueStart; - TW_UINT32 HueEnd; - TW_UINT32 SaturationStart; - TW_UINT32 SaturationEnd; - TW_UINT32 ValueStart; - TW_UINT32 ValueEnd; - TW_UINT32 Replacement; -} TW_FILTER_DESCRIPTOR, *pTW_FILTER_DESCRIPTOR; - -/* DAT_FILTER */ -typedef struct { - TW_UINT32 Size; - TW_UINT32 DescriptorCount; - TW_UINT32 MaxDescriptorCount; - TW_UINT32 Condition; - TW_HANDLE hDescriptors; -} TW_FILTER, *pTW_FILTER; - - -/* Restore the previous packing alignment: this occurs after all structures are defined */ -#ifdef TWH_CMP_MSC - #pragma pack (pop, before_twain) -#elif defined(TWH_CMP_GNU) - #if defined(__APPLE__) /* cf: Mac version of TWAIN.h */ - #pragma options align = reset - #else - #pragma pack (pop, before_twain) - #endif -#elif defined(TWH_CMP_BORLAND) - #pragma option -a. -#endif - -#endif /* TWAIN */ diff --git a/twain/twain/twpp.hpp b/twain/twain/twpp.hpp deleted file mode 100644 index a3d95a1..0000000 --- a/twain/twain/twpp.hpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_TWPP_HPP -#define TWPP_DETAIL_FILE_TWPP_HPP - -#include "twpp/env.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "twpp/utils.hpp" - -#include "twpp/types.hpp" -#include "twpp/strings.hpp" -#include "twpp/fix32.hpp" -#include "twpp/frame.hpp" -#include "twpp/exception.hpp" -#include "twpp/typesops.hpp" - -#include "twpp/memoryops.hpp" -#include "twpp/memory.hpp" - -#include "twpp/enums.hpp" -#include "twpp/status.hpp" -#include "twpp/identity.hpp" -#include "twpp/imageinfo.hpp" -#include "twpp/imagelayout.hpp" -#include "twpp/deviceevent.hpp" -#include "twpp/element8.hpp" - -#include "twpp/audio.hpp" -#include "twpp/capability.hpp" -#include "twpp/customdata.hpp" -#include "twpp/cie.hpp" -#include "twpp/curveresponse.hpp" -#include "twpp/event.hpp" -#include "twpp/extimageinfo.hpp" -#include "twpp/filesystem.hpp" -#include "twpp/imagememxfer.hpp" -#include "twpp/imagenativexfer.hpp" -#include "twpp/internal.hpp" -#include "twpp/jpegcompression.hpp" -#include "twpp/palette8.hpp" -#include "twpp/passthrough.hpp" -#include "twpp/pendingxfers.hpp" -#include "twpp/setupfilexfer.hpp" -#include "twpp/setupmemxfer.hpp" -#include "twpp/userinterface.hpp" - -#if !defined(TWPP_IS_DS) -# include "twpp/application.hpp" -#else -# include "twpp/datasource.hpp" -#endif - - -#if !defined(TWPP_NO_NOTES) -# if !defined(TWPP_IS_DS) -# pragma message ("note: using APPLICATION version of TWPP library, define TWPP_IS_DS before including twpp.hpp if you want DATA SOURCE version") -# if defined(TWPP_DETAIL_OS_WIN32) -# pragma message ("note: place the following into your module-definition (.def) file: EXPORTS DS_Entry @1") -# endif -# else -# pragma message ("note: using DATA SOURCE version of TWPP library, undefine TWPP_IS_DS if you want APPLICATION version") -# pragma message ("note: make sure to place TWPP_ENTRY() macro in exactly one source file") -# endif -# if defined(TWPP_DETAIL_OS_MAC) -# pragma message "warning: Str32, Str64, Str128 and Str255 are not null-terminated" -# endif -# pragma message ("note: to disable notes and warnings, define TWPP_NO_NOTES before including TWPP header") -#endif - - -#endif // TWPP_DETAIL_FILE_TWPP_HPP diff --git a/twain/twain/twpp/application.hpp b/twain/twain/twpp/application.hpp deleted file mode 100644 index 7ad02c7..0000000 --- a/twain/twain/twpp/application.hpp +++ /dev/null @@ -1,1153 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2017 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_APPLICATION_HPP -#define TWPP_DETAIL_FILE_APPLICATION_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -struct ManagerData { - - ManagerData(const Identity& appId) noexcept : - m_appId(appId){} - - Identity m_appId; - DsmState m_state = DsmState::PreSession; - Detail::DsmLib m_lib; - Detail::DsmEntry m_entry = nullptr; - -#if defined(TWPP_DETAIL_OS_WIN) - Handle m_rootWindow; - bool m_ownRootWindow; -#elif defined(TWPP_DETAIL_OS_MAC) - Detail::NSAutoreleasePool m_autoreleasePool; -#elif !defined(TWPP_DETAIL_OS_LINUX) -# error "ManagerData for your platform here" -#endif - -}; - -struct SourceData { - - SourceData(ManagerData* mgr, const Identity& srcIdent) noexcept : - m_mgr(mgr), m_srcId(srcIdent){} - - ManagerData* m_mgr; - std::function m_devEvent; - Handle m_uiHandle; - Identity m_srcId; - DsState m_state = DsState::Closed; - Msg m_readyMsg = Msg::Null; - -#if defined(TWPP_DETAIL_OS_LINUX) - std::mutex m_cbMutex; - std::condition_variable m_cbCond; -#elif !defined(TWPP_DETAIL_OS_WIN) && !defined(TWPP_DETAIL_OS_MAC) -# error "SourceData for your platform here" -#endif - -}; - -} - -class Manager; - -/// A single TWAIN source. -/// Source must belong to a manager in order to perform operations on it. -/// Any valid source instance must be destroyed or at least cleaned by `cleanup` -/// before parent manager is itself destroyed. -/// -/// `call` vs -/// They are ultimately the same: -/// `call` is more suitable for cases that need fixed number of arguments. -/// is better for user-defined calls. -class Source { - - friend class Manager; - -public: - typedef std::function EventCallBack; - - /// Creates an invalid source. - /// Calling any method on such source results in - /// undefined behaviour, and possibly segfault. - /// Only isValid() and operator bool() may be called. - Source() noexcept{} - - ~Source(){ - if (isValid()){ - cleanup(); - } - } - - Source(Source&&) = default; - Source& operator=(Source&& o) noexcept{ - if (&o != this){ - if (isValid()){ - cleanup(); - } - - m_data = std::move(o.m_data); - } - - return *this; - } - - /// Performs explicit cleanup. - /// Ultimately closes the source. - void cleanup() noexcept{ - assert(isValid()); - - PendingXfers xfers; - - switch (d()->m_state){ - case DsState::Xferring: - pendingXfers(Msg::EndXfer, xfers); - // fallthrough - case DsState::XferReady: - if (d()->m_state == DsState::XferReady){ // EndXfer might have moved to DsState::Enabled - pendingXfers(Msg::Reset, xfers); - } - - // fallthrough - case DsState::Enabled: - disable(); - // fallthrough - case DsState::Open: - close(); - // reset the ref even if close() fails somehow - Static::g_openSource = nullptr; - // fallthrough - case DsState::Closed: - break; - } - } - - /// TWAIN state of the source. - DsState state() const noexcept{ - assert(isValid()); - - return d()->m_state; - } - - /// Whether the source is valid. - /// Valid source was created by manager. - /// Invalid source was created using default constructor. - bool isValid() const noexcept{ - return static_cast(m_data); - } - - operator bool() const noexcept{ - return isValid(); - } - - /// Identity of the source. - const Identity& identity() const noexcept{ - assert(isValid()); - - return d()->m_srcId; - } - - /// Sets function (object) to receive device event notifications. - /// - /// {In state 5 (enabled), the function should only set a flag and return immediately. - /// `waitReady()` then returns CheckStatus, and the device event may be processed in - /// the main thread. Call `waitReady()` again once you are done.} - void setEventCallBack(EventCallBack devEvent){ - assert(isValid()); - - d()->m_devEvent = std::move(devEvent); - } - - - // Control -> - - /// Opens the source. - /// Only up to 1 source may be opened at the same time. - /// \throw std::bad_alloc - ReturnCode open(){ - assert(Static::g_openSource == nullptr); - - auto rc = dsm(nullptr, DataGroup::Control, Dat::Identity, Msg::OpenDs, d()->m_srcId); - if (success(rc)){ - d()->m_state = DsState::Open; - - // TWAIN manual is rather confusing on this topic. - // Their example sends the registration to DSM, operation tripet documentation mentions DS as destination. - // Looking at some other applications, Windows seems to send this to DS, MacOS to DSM. - Detail::CallBack cb1(callBack, static_cast(0), Msg::Null); - -#if defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) - Detail::CallBack2 cb2(callBack, 0, Msg::Null); - - bool usesCb = success(dsm(DataGroup::Control, Dat::Callback2, Msg::RegisterCallback, cb2)) || - success(dsm(DataGroup::Control, Dat::Callback, Msg::RegisterCallback, cb1)); -#elif defined(TWPP_DETAIL_OS_MAC) - bool usesCb = success(dsm(nullptr, DataGroup::Control, Dat::Callback, Msg::RegisterCallback, cb1)); -#else -# error "callback setup for your platform here" -#endif - -#if defined(TWPP_DETAIL_OS_WIN) - Detail::unused(usesCb); -#elif defined(TWPP_DETAIL_OS_MAC) || defined(TWPP_DETAIL_OS_LINUX) - if (!usesCb){ - close(); - return ReturnCode::Failure; - } -#else -# error "source open setup for your platform here" -#endif - Static::g_openSource = d(); - } - - return rc; - } - - /// Closes the source. - ReturnCode close(){ - ReturnCode rc = dsm(nullptr, DataGroup::Control, Dat::Identity, Msg::CloseDs, d()->m_srcId); - if (success(rc)){ - Static::g_openSource = nullptr; - d()->m_state = DsState::Closed; - } - - return rc; - } - - /// Enables the source, showing its GUI if requested. - /// A call to `waitReady` must follow, advanced users may look at `processEvent` on Windows. - /// \param ui GUI settings. - /// \param uiOnly Whether the GUI should only be used to change values, not scan. - ReturnCode enable(const UserInterface& ui, bool uiOnly = false) noexcept{ - auto uiTmp = ui; // allow ui to be const, dsm doesnt take const - ReturnCode rc = dsm(DataGroup::Control, Dat::UserInterface, uiOnly ? Msg::EnableDsUiOnly : Msg::EnableDs, uiTmp); - if (success(rc) || (!uiOnly && rc == ReturnCode::CheckStatus)){ - d()->m_readyMsg = Msg::Null; - d()->m_uiHandle = ui.parent(); - d()->m_state = DsState::Enabled; - } - - return rc; - } - - /// Disables this source. - ReturnCode disable(){ - assert(isValid()); - - UserInterface ui(false, false, d()->m_uiHandle); - auto rc = dsm(DataGroup::Control, Dat::UserInterface, Msg::DisableDs, ui); - if (success(rc)){ - d()->m_state = DsState::Open; - } - - return rc; - } - - /// Waits on source GUI, blocking. - /// This method is meant for CMD applications, see `processEvent()` for GUI-friendly version. - /// The state is moved to XferReady, when Success is returned, and the source is enabled with full UI (uiOnly = false). - /// On Windows and Mac OS, call this method from the main thread, GUI events are processed here. - /// On Linux, this method may be called from any thread, GUI events are NOT processed. - /// Call this again after processing device event. - /// \return {Failure on error, Cancel on CANCEL button, Success on SAVE or SCAN button, - /// CheckStatus on device event.} - ReturnCode waitReady(){ - assert(isValid()); - - if (d()->m_state != DsState::Enabled){ - return ReturnCode::Failure; - } - -#if defined(TWPP_DETAIL_OS_WIN) - MSG msg; - memset(&msg, 0, sizeof(msg)); - - Event event(&msg, Msg::Null); - while (d()->m_readyMsg == Msg::Null){ - auto val = GetMessage(&msg, nullptr, 0, 0); - if (val == 0 || val == -1){ // 0 ... WM_QUIT; -1 ... error; otherwise ... success - return ReturnCode::Failure; - } - - auto rc = dsm(DataGroup::Control, Dat::Event, Msg::ProcessEvent, event); - switch (rc){ - case ReturnCode::NotDsEvent: - TranslateMessage(&msg); - DispatchMessage(&msg); - // fallthrough - case ReturnCode::DsEvent: - if (d()->m_readyMsg == Msg::Null){ - d()->m_readyMsg = event.message(); - } - - break; - - default: - return rc; - } - } -#elif defined(TWPP_DETAIL_OS_MAC) - Detail::NSAutoreleasePool pool; - - while(d()->m_readyMsg == Msg::Null) { - Detail::NSLoop::processEvent(); - } - - pool.release(); - -#elif defined(TWPP_DETAIL_OS_LINUX) - std::unique_lock lock(d()->m_cbMutex); - while (d()->m_readyMsg == Msg::Null){ - d()->m_cbCond.wait(lock); - } -#else -# error "waitReady for your platform here" -#endif - - switch (d()->m_readyMsg){ - case Msg::XferReady: // ok/scan button <=> Msg::EnableDs - d()->m_state = DsState::XferReady; - case Msg::CloseDsOk: // ok/scan button <=> Msg::EnableDsUiOnly - return ReturnCode::Success; - - case Msg::CloseDsReq: // cancel button - return ReturnCode::Cancel; - - case Msg::DeviceEvent: - d()->m_readyMsg = Msg::Null; - return ReturnCode::CheckStatus; - - default: - return ReturnCode::Failure; - } - } - - /// Processes a single GUI event without blocking. - /// Can be used instead of `waitReady()` to process a single event. - /// Windows users must pass events from GUI loop to this method to be sent to DS. - /// \return {Failure on error, Cancel on CANCEL button, Success on SAVE or SCAN button, - /// CheckStatus on device event. NotDsEvent OR DsEvent when not ready yet.} -#if defined (TWPP_DETAIL_OS_WIN) - ReturnCode processEvent(MSG* event){ - Event twEvent(event, Msg::Null); - auto rc = dsm(DataGroup::Control, Dat::Event, Msg::ProcessEvent, twEvent); - switch (rc){ - case ReturnCode::DsEvent: - case ReturnCode::NotDsEvent: - if (d()->m_readyMsg == Msg::Null){ - d()->m_readyMsg = twEvent.message(); - } - - break; - - default: - return rc; - } - - auto msg = d()->m_readyMsg; - -#elif defined(TWPP_DETAIL_OS_LINUX) || defined(TWPP_DETAIL_OS_MAC) - ReturnCode processEvent(){ - assert(isValid()); - auto rc = ReturnCode::NotDsEvent; - -# if defined(TWPP_DETAIL_OS_MAC) - auto msg = d()->m_readyMsg; -# else - std::unique_lock lock(d()->m_cbMutex); - auto msg = d()->m_readyMsg; - lock.unlock(); -# endif - -#else -# error "processEvent for your platform here" -#endif - switch (msg){ - case Msg::XferReady: // ok/scan button <=> Msg::EnableDs - d()->m_state = DsState::XferReady; - // fallthrough - case Msg::CloseDsOk: // ok/scan button <=> Msg::EnableDsUiOnly - return ReturnCode::Success; - - case Msg::CloseDsReq: // cancel button - return ReturnCode::Cancel; - - case Msg::DeviceEvent: - d()->m_readyMsg = Msg::Null; - return ReturnCode::CheckStatus; - - case Msg::Null: - return rc; - - default: - return ReturnCode::Failure; - } - } - - /// Sends custom, user-defined data to the source. - /// This operation is unsafe, there is no way to discover - /// possible connection state changes. - /// \tparam T Data type. - /// \param dg Data group. - /// \param dat Custom data type identifier. Dat::CustomBase and greater. - /// \param msg Message, action to perform. - /// \param data Custom data. - template - ReturnCode customBase(DataGroup dg, Dat dat, Msg msg, T& data){ - return dsm(dg, dat, msg, data); - } - - /// Sends custom, user-defined data to the source. - /// This operation is unsafe, there is no way to discover - /// possible connection state changes. - /// \param dg Data group. - /// \param dat Custom data type identifier. Dat::CustomBase and greater. - /// \param msg Message, action to perform. - /// \param data Custom data. - ReturnCode customBase(DataGroup dg, Dat dat, Msg msg, void* data){ - return dsmPtr(dg, dat, msg, data); - } - - ReturnCode capability(Msg msg, Capability& inOut){ - return call(DataGroup::Control, msg, inOut); - } - - /// \throw CapTypeException When input capability type does not match the - /// capability type of this template class. - /// \throw CapItemTypeException When input capability item type does not match - /// the expected item type of the capability. - template - ReturnCode capability(Msg msg, Cap& inOut){ - return call(DataGroup::Control, msg, inOut); - } - - ReturnCode customData(Msg msg, CustomData& inOut){ - return call(DataGroup::Control, msg, inOut); - } - - ReturnCode deviceEvent(DeviceEvent& out){ - return call(DataGroup::Control, Msg::Get, out); - } - - ReturnCode fileSystem(Msg msg, FileSystem& inOut){ - return call(DataGroup::Control, msg, inOut); - } - - ReturnCode passThrough(PassThrough& inOut){ - return call(DataGroup::Control, Msg::PassThrough, inOut); - } - - ReturnCode pendingXfers(Msg msg, PendingXfers& inOut){ - return call(DataGroup::Control, msg, inOut); - } - - ReturnCode setupFileXfer(Msg msg, SetupFileXfer& inOut){ - return call(DataGroup::Control, msg, inOut); - } - - ReturnCode setupMemXfer(SetupMemXfer& out){ - return call(DataGroup::Control, Msg::Get, out); - } - - ReturnCode xferGroup(Msg msg, DataGroup& inOut){ - return call(DataGroup::Control, msg, inOut); - } - - ReturnCode status(Status& out){ - return call(DataGroup::Control, Msg::Get, out); - } - - ReturnCode statusUtf8(StatusUtf8& inOut){ - return call(DataGroup::Control, Msg::Get, inOut); - } - // <- Control - - - // Image -> - // TODO CieColor - /* - ReturnCode cieColor(CieColor& out){ - return call(DataGroup::Image, Msg::Get, out); - }*/ - - ReturnCode extImageInfo(ExtImageInfo& inOut){ - return call(DataGroup::Image, Msg::Get, inOut); - } - - ReturnCode grayResponse(Msg msg, GrayResponse& inOut){ - return call(DataGroup::Image, msg, inOut); - } - - ReturnCode iccProfile(IccProfileMemory& out){ - return call(DataGroup::Image, Msg::Get, out); - } - - ReturnCode imageFileXfer(){ - return call(DataGroup::Image, Msg::Get, ImageFileXfer()); - } - - ReturnCode imageInfo(ImageInfo& out){ - return call(DataGroup::Image, Msg::Get, out); - } - - ReturnCode imageLayout(Msg msg, ImageLayout& inOut){ - return call(DataGroup::Image, msg, inOut); - } - - ReturnCode imageMemFileXfer(ImageMemFileXfer& inOut){ - return call(DataGroup::Image, Msg::Get, inOut); - } - - ReturnCode imageMemXfer(ImageMemXfer& inOut){ - return call(DataGroup::Image, Msg::Get, inOut); - } - - ReturnCode imageNativeXfer(ImageNativeXfer& out){ - return call(DataGroup::Image, Msg::Get, out); - } - - ReturnCode jpegCompression(Msg msg, JpegCompression& inOut){ - return call(DataGroup::Image, msg, inOut); - } - - ReturnCode palette8(Msg msg, Palette8& inOut){ - return call(DataGroup::Image, msg, inOut); - } - - ReturnCode rgbResponse(Msg msg, RgbResponse& inOut){ - return call(DataGroup::Image, msg, inOut); - } - // <- Image - - - // Audio -> - ReturnCode audioFileXfer(){ - return call(DataGroup::Audio, Msg::Get, AudioFileXfer()); - } - - ReturnCode audioInfo(AudioInfo& out){ - return call(DataGroup::Audio, Msg::Get, out); - } - - ReturnCode audioNativeXfer(AudioNativeXfer& out){ - return call(DataGroup::Audio, Msg::Get, out); - } - // <- Audio - - - // Raw -> - - // dg:: control follows - ReturnCode call(DataGroup dg, Msg msg, Capability& data){ - return dsm(dg, Dat::Capability, msg, data); - } - - /// \throw CapTypeException When input capability type does not match the - /// capability type of this template class. - /// \throw CapItemTypeException When input capability item type does not match - /// the expected item type of the capability. - template - ReturnCode call(DataGroup dg, Msg msg, Cap& data){ - auto rc = call(dg, msg, data.m_cap); - data.checkTypes(); - return rc; - } - - ReturnCode call(DataGroup dg, Msg msg, CustomData& data){ - return dsm(dg, Dat::CustomData, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, DeviceEvent& data){ - return dsm(dg, Dat::DeviceEvent, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, FileSystem& data){ - return dsm(dg, Dat::FileSystem, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, PassThrough& data){ - return dsm(dg, Dat::PassThrough, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, PendingXfers& data){ - auto rc = dsm(dg, Dat::PendingXfers, msg, data); - if (success(rc)){ - // FIXME: unsure about audio state transitions - DataGroup xg = DataGroup::Image; - switch (msg){ - case Msg::EndXfer: - xferGroup(Msg::Get, xg); - if (xg == DataGroup::Image && data.count() == 0){ - d()->m_state = DsState::Enabled; - } else { - d()->m_state = DsState::XferReady; - } - - break; - - case Msg::Reset: - xferGroup(Msg::Get, xg); - if (xg == DataGroup::Image){ - d()->m_state = DsState::Enabled; - } - - break; - - default: - break; - } - - - } - - return rc; - } - - ReturnCode call(DataGroup dg, Msg msg, SetupFileXfer& data){ - return dsm(dg, Dat::SetupFileXfer, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, SetupMemXfer& data){ - return dsm(dg, Dat::SetupMemXfer, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, DataGroup& data){ - return dsm(dg, Dat::XferGroup, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, Status& data){ - return dsm(dg, Dat::Status, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, StatusUtf8& data){ - return dsm(dg, Dat::StatusUtf8, msg, data); - } - - // dg::image follows - // TODO CieColor - /* - ReturnCode call(DataGroup dg, Msg msg, CieColor& data){ - return dsm(dg, Dat::CieColor, msg, data); - }*/ - - ReturnCode call(DataGroup dg, Msg msg, ExtImageInfo& data){ - char* raw = *Detail::alias_cast(&data); // ExtImageInfo is just an envelope; raw ~ ExtImageInfo.m_data - return dsmPtr(dg, Dat::ExtImageInfo, msg, raw); - } - - ReturnCode call(DataGroup dg, Msg msg, GrayResponse& data){ - return dsmPtr(dg, Dat::GrayResponse, msg, data.data()); - } - - ReturnCode call(DataGroup dg, Msg msg, IccProfileMemory& data){ - Memory mem; // DS allocates and owns the memory - ReturnCode rc = dsm(dg, Dat::IccProfile, msg, mem); - if (success(rc)){ - data = std::move(mem); - } - - return rc; - } - - ReturnCode call(DataGroup dg, Msg msg, const ImageFileXfer&){ - ReturnCode rc = dsmPtr(dg, Dat::ImageFileXfer, msg, nullptr); - if (success(rc)){ - d()->m_state = DsState::Xferring; - } - - return rc; - } - - ReturnCode call(DataGroup dg, Msg msg, ImageInfo& data){ - return dsm(dg, Dat::ImageInfo, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, ImageLayout& data){ - return dsm(dg, Dat::ImageLayout, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, ImageMemFileXfer& data){ - ReturnCode rc = dsm(dg, Dat::ImageMemFileXfer, msg, data); - if (success(rc) || rc == ReturnCode::XferDone){ - d()->m_state = DsState::Xferring; - } - - return rc; - } - - ReturnCode call(DataGroup dg, Msg msg, ImageMemXfer& data){ - ReturnCode rc = dsm(dg, Dat::ImageMemXfer, msg, data); - if (success(rc) || rc == ReturnCode::XferDone){ - d()->m_state = DsState::Xferring; - } - - return rc; - } - - ReturnCode call(DataGroup dg, Msg msg, ImageNativeXfer& data){ - Handle h; - ReturnCode rc = dsm(dg, Dat::ImageNativeXfer, msg, h); - if (rc == ReturnCode::XferDone){ - d()->m_state = DsState::Xferring; - } - - if (h){ - data = ImageNativeXfer(h); - } - - return rc; - } - - ReturnCode call(DataGroup dg, Msg msg, JpegCompression& data){ - return dsm(dg, Dat::JpegCompression, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, Palette8& data){ - return dsm(dg, Dat::Palette8, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, RgbResponse& data){ - return dsmPtr(dg, Dat::RgbResponse, msg, data.data()); - } - - // dg::audio follows - ReturnCode call(DataGroup dg, Msg msg, const AudioFileXfer&){ - // FIXME: unsure about state transitions - ReturnCode rc = dsmPtr(dg, Dat::AudioFileXfer, msg, nullptr); - if (rc == ReturnCode::XferDone){ - d()->m_state = DsState::Xferring; - } - - return rc; - } - - ReturnCode call(DataGroup dg, Msg msg, AudioInfo& data){ - return dsm(dg, Dat::AudioInfo, msg, data); - } - - ReturnCode call(DataGroup dg, Msg msg, AudioNativeXfer& data){ - Handle h; - ReturnCode rc = dsm(dg, Dat::AudioNativeXfer, msg, h); - if (success(rc)){ - d()->m_state = DsState::Xferring; - } - - if (h){ - data = AudioNativeXfer(h); - } - - return rc; - } - // <- Raw - -private: - Source(Detail::ManagerData* mgr, const Identity& srcId) : - m_data(new Detail::SourceData(mgr, srcId)){} - - Detail::SourceData* d() noexcept{ - return m_data.get(); - } - - const Detail::SourceData* d() const noexcept{ - return m_data.get(); - } - - template - ReturnCode dsm(Identity* dest, DataGroup dg, Dat dat, Msg msg, T& data) noexcept{ - return dsmPtr(dest, dg, dat, msg, &data); - } - - ReturnCode dsmPtr(Identity* dest, DataGroup dg, Dat dat, Msg msg, void* data) noexcept{ - assert(isValid()); - - auto mgr = d()->m_mgr; - return mgr->m_entry(&mgr->m_appId, dest, dg, dat, msg, data); - } - - template - ReturnCode dsm(DataGroup dg, Dat dat, Msg msg, T& data) noexcept{ - return dsm(&d()->m_srcId, dg, dat, msg, data); - } - - ReturnCode dsmPtr(DataGroup dg, Dat dat, Msg msg, void* data) noexcept{ - return dsmPtr(&d()->m_srcId, dg, dat, msg, data); - } - - // header-only, yet we need static variables - // templates behave as if defined in at most one source file - template - struct Static { - static Detail::SourceData* g_openSource; - }; - - template - static ReturnCode TWPP_DETAIL_CALLSTYLE callBack( - Identity*, - Identity*, - DataGroup, - Dat, - Msg msg, - void* - ) noexcept{ - Detail::SourceData* src = Static::g_openSource; - if (src == nullptr){ - return ReturnCode::Failure; - } - -#if defined(TWPP_DETAIL_OS_LINUX) - std::unique_lock lock(src->m_cbMutex); - if (src->m_state != DsState::Enabled){ - lock.unlock(); - } -#elif !defined(TWPP_DETAIL_OS_WIN) && !defined(TWPP_DETAIL_OS_MAC) -# error "callBack preparation for your platform here" -#endif - if (msg == Msg::DeviceEvent){ - if (!src->m_devEvent){ - return ReturnCode::Failure; - } - - src->m_devEvent(); - } - - if (src->m_state == DsState::Enabled){ - src->m_readyMsg = msg; - -#if defined(TWPP_DETAIL_OS_WIN) - PostMessageA(static_cast(src->m_mgr->m_rootWindow.raw()), WM_NULL, 0, 0); -#elif defined(TWPP_DETAIL_OS_LINUX) - src->m_cbCond.notify_one(); -#elif defined(TWPP_DETAIL_OS_MAC) - Detail::NSLoop::postDummy(); -#else -# error "callBack for your platform here" -#endif - } - - - return ReturnCode::Success; - } - - std::unique_ptr m_data; - -}; - -template -Detail::SourceData* Source::Static::g_openSource = nullptr; - -/// TWAIN data source manager. -/// At most one valid instance may exist at all times. -/// All corresponding valid sources must be destroyed or cleaned up -/// BEFORE their parent valid manager is closed (destroyed/cleaned up). -class Manager { - -public: - /// Creates an invalid manager. - Manager() noexcept{} - - /// Creates a valid, unloaded manager. - /// \param appIdentity Application identity. - explicit Manager(const Identity& appIdentity) : - m_data(new Detail::ManagerData(appIdentity)){} - - ~Manager(){ - if (isValid()){ - cleanup(); - } - } - - Manager(Manager&&) = default; - Manager& operator=(Manager&& o) noexcept{ - if (&o != this){ - if (isValid()){ - cleanup(); - } - - m_data = std::move(o.m_data); - } - - return *this; - } - - /// Explicitly cleanes the manager, ultimately closing it. - void cleanup() noexcept{ - assert(isValid()); - - switch (d()->m_state){ - case DsmState::Open: - close(); - // fallthrough - case DsmState::Loaded: - unload(); - // fallthrough - case DsmState::PreSession: - // nothing to do now - break; - } - } - - /// Loads the manager library. - /// Not a TWAIN call. - /// \param preferOld {Whether to prefer old DSM (TWAIN_32) instead - /// of the new one (TWAINDSM) on 32bit Windows. - /// Has no effect anywhere else.} - /// \return Whether this call loaded the library. - bool load(bool preferOld = false) noexcept{ - assert(isValid()); - - if (d()->m_state != DsmState::PreSession){ - return false; - } - - if (!d()->m_lib.load(preferOld)){ - return false; - } - - d()->m_state = DsmState::Loaded; - d()->m_entry = d()->m_lib.resolve(); - bool resolved = d()->m_entry != nullptr; - if (!resolved){ - unload(); - } - - return resolved; - } - - /// Unloads the manager library. - /// Not a TWAIN call. - /// \return Whether this call unloaded the library. - bool unload() noexcept{ - assert(isValid()); - - if (d()->m_state != DsmState::Loaded){ - return false; - } - - closeRootWindow(); - d()->m_lib.unload(); - d()->m_state = DsmState::PreSession; - return true; - } - - /// Opens the manager. - ReturnCode open(Handle rootWindow = Handle()) noexcept{ - assert(isValid()); - - if (d()->m_state != DsmState::Loaded){ - return ReturnCode::Failure; - } - -#if defined(TWPP_DETAIL_OS_WIN) - if (rootWindow){ - closeRootWindow(); - d()->m_rootWindow = rootWindow; - d()->m_ownRootWindow = false; - } else { - if (!d()->m_rootWindow || !d()->m_ownRootWindow){ - d()->m_rootWindow = Handle(CreateWindowA("STATIC", nullptr, 0, 0, 0, 0, 0, nullptr, nullptr, nullptr, nullptr)); - if (!d()->m_rootWindow){ - return ReturnCode::Failure; - } - } - - d()->m_ownRootWindow = true; - rootWindow = d()->m_rootWindow; - } -#elif !defined(TWPP_DETAIL_OS_MAC) && !defined(TWPP_DETAIL_OS_LINUX) -# error "manager open setup for your platform here" -#endif - - auto rc = dsm(nullptr, DataGroup::Control, Dat::Parent, Msg::OpenDsm, rootWindow); - if (success(rc)){ - Detail::resetMemFuncs(); - if (d()->m_appId.isDsmV2()){ - Detail::EntryPoint e; - if (success(dsm(nullptr, DataGroup::Control, Dat::EntryPoint, Msg::Get, e))){ - Detail::setMemFuncs(e.m_alloc, e.m_free, e.m_lock, e.m_unlock); - } - } - - d()->m_state = DsmState::Open; - } - - return rc; - } - - /// Closes the manager. - ReturnCode close() noexcept{ - assert(isValid()); - - // no need to check state, dsm will do it for us - -#if defined(TWPP_DETAIL_OS_WIN) - Handle rootWindow = d()->m_rootWindow; -#elif defined(TWPP_DETAIL_OS_MAC) || defined(TWPP_DETAIL_OS_LINUX) - Handle rootWindow; -#else -# error "close manager for your platform here" -#endif - - auto rc = dsm(nullptr, DataGroup::Control, Dat::Parent, Msg::CloseDsm, rootWindow); - if (success(rc)){ - d()->m_state = DsmState::Loaded; - } - - return rc; - } - - /// Creates a valid closed source. - /// Whether the source may be opened depends whether - /// a source with the supplied product name and manufacturer exists. - /// \throw std::bad_alloc - Source createSource(const Str32& productName, const Str32& manufacturer){ - assert(isValid()); - - return Source(d(), Identity(Version(), DataGroup::Control, manufacturer, Str32(), productName)); - } - - /// Creates a valid closed default source. - /// It is almost certain the source may be opened. - /// \throw std::bad_alloc - ReturnCode defaultSource(Source& out){ - Identity id; - auto rc = dsm(nullptr, DataGroup::Control, Dat::Identity, Msg::GetDefault, id); - if (success(rc)){ - out = Source(d(), id); - } - - return rc; - } - - /// Sets default source. - ReturnCode setDefaultSource(Source& in) noexcept{ - return dsm(nullptr, DataGroup::Control, Dat::Identity, Msg::Set, in.d()->m_srcId); - } - - /// Lists all available sources. - /// \tparam Container Container type, usually std::vector. - /// \param out The container to be filled with sources. - /// \return {RC::Success if one source, RC::EndOfList if more sources, RC::Failure if error.} - template - ReturnCode sources(Container& out){ - Identity id; - auto rc = dsm(nullptr, DataGroup::Control, Dat::Identity, Msg::GetFirst, id); - if (success(rc)){ - do { - out.push_back(Source(d(), id)); - - rc = dsm(nullptr, DataGroup::Control, Dat::Identity, Msg::GetNext, id); - } while(success(rc)); - } - - return rc; - } - - /// Shows a source-selection dialog. - /// Available only on Windows and MacOS. - ReturnCode showSourceDialog(Source& out){ - Identity id; - ReturnCode rc = dsm(nullptr, DataGroup::Control, Dat::Identity, Msg::UserSelect, id); - if (success(rc)){ - out = Source(d(), id); - } - - return rc; - } - - /// Obtains the last manager status. - ReturnCode status(Status& status) noexcept{ - return dsm(nullptr, DataGroup::Control, Dat::Status, Msg::Get, status); - } - - /// The current manager TWAIN state. - DsmState state() const noexcept{ - assert(isValid()); - - return d()->m_state; - } - - /// Application identity the manager was/will be open with. - const Identity& identity() const noexcept{ - assert(isValid()); - - return d()->m_appId; - } - - /// Whether this object is a valid manager. - /// Valid manager object is created using constructor with at least one parameter. - /// Using constructor without any parameters results in invalid manager. - bool isValid() const noexcept{ - return static_cast(m_data); - } - - operator bool() noexcept{ - return isValid(); - } - -private: - void closeRootWindow() noexcept{ -#if defined(TWPP_DETAIL_OS_WIN) - if (d()->m_rootWindow && d()->m_ownRootWindow){ - DestroyWindow(static_cast(d()->m_rootWindow.raw())); - d()->m_ownRootWindow = Handle(); - } -#elif !defined(TWPP_DETAIL_OS_MAC) && !defined(TWPP_DETAIL_OS_LINUX) -# error "closeRootWindow for your platform here" -#endif - } - - Detail::ManagerData* d() noexcept{ - return m_data.get(); - } - - const Detail::ManagerData* d() const noexcept{ - return m_data.get(); - } - - template - ReturnCode dsm(Identity* dest, DataGroup dg, Dat dat, Msg msg, T& data){ - return dsmPtr(dest, dg, dat, msg, &data); - } - - ReturnCode dsmPtr(Identity* dest, DataGroup dg, Dat dat, Msg msg, void* data){ - assert(isValid()); - - return d()->m_entry(&d()->m_appId, dest, dg, dat, msg, data); - } - - std::unique_ptr m_data; - -}; - -} - -#endif // TWPP_DETAIL_FILE_APPLICATION_HPP - diff --git a/twain/twain/twpp/audio.hpp b/twain/twain/twpp/audio.hpp deleted file mode 100644 index 6aa8491..0000000 --- a/twain/twain/twpp/audio.hpp +++ /dev/null @@ -1,119 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_AUDIO_HPP -#define TWPP_DETAIL_FILE_AUDIO_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Information about current audio transfer. -/// ArgType::AudioInfo -class AudioInfo { - -public: - /// Creates empty audio info. - constexpr AudioInfo() noexcept : - m_name(), m_reserved(){} - - /// Creates audio info with set name of audio data. - explicit constexpr AudioInfo(const Str255& name, UInt32 reserved = 0) noexcept : - m_name(name), m_reserved(reserved){} - - /// Name of audio data. - constexpr const Str255& name() const noexcept{ - return m_name; - } - - /// Name of audio data. - Str255& name() noexcept{ - return m_name; - } - - constexpr UInt32 reserved() const noexcept{ - return m_reserved; - } - - void setReserved(UInt32 reserved) noexcept{ - m_reserved = reserved; - } - -private: - Str255 m_name; - UInt32 m_reserved; - -}; - -/// Owner of audio transfer handle. -class AudioNativeXfer { - -public: - template - using Data = Detail::Lock::type>; - - template - using ConstData = Detail::Lock::type>; - - - /// Creates an empty handle owner. - AudioNativeXfer() noexcept : - m_handle(){} - - /// Creates a memory area of desired size for audio native transfer. - /// \throw std::bad_alloc - explicit AudioNativeXfer(UInt32 size) : - m_handle(Detail::alloc(size)){} - - /// Audio data. - template - Data data() noexcept{ - return m_handle.lock::type>(); - } - - /// Audio data. - template - ConstData data() const noexcept{ - return m_handle.lock::type>(); - } - - /// Releases the owned handle. - /// The user becomes responsible for freeing the handle. - Handle release() noexcept{ - return m_handle.release(); - } - -private: - Detail::UniqueHandle m_handle; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_AUDIO_HPP - diff --git a/twain/twain/twpp/capability.hpp b/twain/twain/twpp/capability.hpp deleted file mode 100644 index 6f08b43..0000000 --- a/twain/twain/twpp/capability.hpp +++ /dev/null @@ -1,2323 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_CAPABILITY_HPP -#define TWPP_DETAIL_FILE_CAPABILITY_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -/// Mapping of capability type to type identifier and data type. -template struct Cap {}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Alarm DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int32; typedef Int32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str128; typedef Str128 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int32; typedef Int32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef XferMech DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int32; typedef Int32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int16; typedef Int16 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PixelType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef CameraSide DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef ClearBuffers DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef DeviceEvent::Type DataType;}; // Capability->UInt16, DeviceEvent->UInt32 -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str32; typedef Str32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef DoubleFeedDetection DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef DoubleFeedResponse DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef DoubleFeedSensitivity DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Duplex DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef CapType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef FeederAlignment DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef FeederOrder DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef FeederPocket DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int32; typedef DiscardBlankPages DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PixelType DataType;}; // only BW/Gray -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef AutoSize DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef SearchMode DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef BarCodeType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef UInt16 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef BitDepthReduction DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef BitOrder DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef BitOrder DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef UInt16 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Compression DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt8; typedef UInt8 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef FeederType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef FilmType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Filter DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Flash DataType;}; // Capability->UInt16, DeviceEvent->UInt32 -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef FlipRotation DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Frame; typedef Frame DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str32; typedef Str32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef IccProfile DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef ImageFileFormat DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef ImageFilter DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef ImageMerge DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PixelType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef JpegQuality DataType;}; // JpegQuality or 0-100 -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef JpegSubSampling DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef LightPath DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef LightSource DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef UInt16 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Mirror DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef IndicatorsMode DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef NoiseFilter DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Orientation DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef OverScan DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef SearchMode DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PatchCode DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PixelFlavor DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PixelFlavor DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PixelType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef ColorFormat DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef BarCodeType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Twpp::InfoId DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PatchCode DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PaperSize DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef UInt16 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Unit DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef XferMech DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int16; typedef Int16 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef JobControl DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Language DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PaperHandling DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int32; typedef Int32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PowerSupply DataType;}; // Capability->UInt16, DeviceEvent->Int32 -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Printer DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef FontStyle DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str32; typedef Str32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef IndexTrigger DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef PrinterMode DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Fix32; typedef Fix32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef Segmented DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef CapType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt16; typedef CapType DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int32; typedef Int32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int32; typedef Int32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Str32; typedef Str32 DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Cap {static constexpr const Type twty = Type::Int16; typedef Int16 DataType;}; - -TWPP_DETAIL_PACK_BEGIN -// certain apps assume that size of OneValue item is always at least 4 bytes -// add padding that extends the sign of signed integers -// and pads with zeroes for unsigned integers -// all other cases use their data types directly -template // false, any -struct OneValueProxy { - OneValueProxy& operator=(const DataType& value) noexcept{ - m_data = value; - return *this; - } - - operator const DataType&() const noexcept{ - return m_data; - } - - operator DataType&() noexcept{ - return m_data; - } - - DataType m_data; -}; - -template -struct OneValueProxy { - OneValueProxy& operator=(DataType value) noexcept{ - m_signed = static_cast(value); - return *this; - } - - operator DataType() const noexcept{ - return m_data; - } - - operator DataType&() noexcept{ - return m_data; - } - - union { - DataType m_data; - Int32 m_signed; - }; -}; - -template -struct OneValueProxy { - OneValueProxy& operator=(DataType value) noexcept{ - m_unsigned = static_cast(value); - return *this; - } - - operator DataType() const noexcept{ - return m_data; - } - - operator DataType&() noexcept{ - return m_data; - } - - union { - DataType m_data; - UInt32 m_unsigned; - }; -}; - -template -struct OneValueData { - Type m_itemType; - OneValueProxy::value> m_item; -}; - -template -struct ArrayData { - Type m_itemType; - UInt32 m_numItems; - DataType m_items[1]; -}; - -template -struct EnumerationData { - Type m_itemType; - UInt32 m_numItems; - UInt32 m_currIndex; - UInt32 m_defIndex; - DataType m_items[1]; -}; - -// Range items are always 4 bytes large, -// add padding for smaller data types -template -struct RangeProxy { - typedef typename std::conditional< - std::is_signed::value, Int32, UInt32 - >::type InnerType; - - RangeProxy& operator=(DataType value) noexcept{ - m_data = value; - return *this; - } - - operator DataType() const noexcept{ - return static_cast(m_data); - } - - operator DataType&() noexcept{ - return *alias_cast(&m_data); - } - - InnerType m_data; -}; - -template<> -struct RangeProxy { - RangeProxy& operator=(Fix32 value) noexcept{ - m_data = value; - return *this; - } - - operator Fix32() const noexcept{ - return m_data; - } - - operator Fix32&() noexcept{ - return m_data; - } - - Fix32 m_data; -}; - -template -struct RangeData { - Type m_itemType; - RangeProxy m_minValue; - RangeProxy m_maxValue; - RangeProxy m_stepSize; - RangeProxy m_defValue; - RangeProxy m_currValue; -}; -TWPP_DETAIL_PACK_END - - -template -struct IsNumeric { - static constexpr bool value = std::is_integral::value || std::is_same::value; -}; - -} - -class Capability; - -/// Capability container holding a single value. -/// \tparam twty ID of the internal data type. -/// \tparam DataType Exported data type. -template::Type> -class OneValue { - - friend class Capability; - -public: - static constexpr const ConType contype = ConType::OneValue; - typedef DataType* iterator; - typedef const DataType* const_iterator; - - /// Creates an invalid container. - constexpr OneValue() noexcept{} - - /// ID of the internal data type. - Type type() const noexcept{ - return m_data->m_itemType; - } - - /// The contained value. - DataType& item() noexcept{ - return m_data->m_item; - } - - /// The contained value. - const DataType& item() const noexcept{ - return m_data->m_item; - } - - /// Sets the contained value. - void setItem(const DataType& item) noexcept{ - m_data->m_item = item; - } - - operator bool() const noexcept{ - return m_data; - } - - - iterator begin() noexcept{ - return &m_data->m_item; - } - - const_iterator begin() const noexcept{ - return cbegin(); - } - - const_iterator cbegin() const noexcept{ - return &m_data->m_item; - } - - iterator end() noexcept{ - return &m_data->m_item + 1; - } - - const_iterator end() const noexcept{ - return cend(); - } - - const_iterator cend() const noexcept{ - return &m_data->m_item + 1; - } - -private: - OneValue(Handle h) : m_data(h){} - - Detail::Lock > m_data; - -}; - -// disable OneValue for incompatible types -template -class OneValue; -template -class OneValue; - - -/// Capability container holding an array of values. -/// \tparam twty ID of the internal data type. -/// \tparam DataType Exported data type. -template::Type> -class Array { - - friend class Capability; - -public: - static constexpr const ConType contype = ConType::Array; - typedef DataType* iterator; - typedef const DataType* const_iterator; - - /// Creates an invalid container. - constexpr Array() noexcept{} - - /// ID of the internal data type. - Type type() const noexcept{ - return m_data->m_itemType; - } - - /// Number of items in the array. - UInt32 size() const noexcept{ - return m_data->m_numItems; - } - - /// Access contained value in array. - DataType& at(std::size_t i) noexcept{ - return m_data->m_items[i]; - } - - /// Access contained value in array. - const DataType& at(std::size_t i) const noexcept{ - return m_data->m_items[i]; - } - - /// Sets value in array. - void set(std::size_t i, const DataType& val) noexcept{ - at(i) = val; - } - - - DataType& operator[](std::size_t i) noexcept{ - return at(i); - } - - const DataType& operator[](std::size_t i) const noexcept{ - return at(i); - } - - operator bool() const noexcept{ - return m_data; - } - - - iterator begin() noexcept{ - return m_data->m_items; - } - - const_iterator begin() const noexcept{ - return cbegin(); - } - - const_iterator cbegin() const noexcept{ - return m_data->m_items; - } - - iterator end() noexcept{ - return m_data->m_items + m_data->m_numItems; - } - - const_iterator end() const noexcept{ - return cend(); - } - - const_iterator cend() const noexcept{ - return m_data->m_items + m_data->m_numItems; - } - -private: - Array(Handle h) : m_data(h){} - - Detail::Lock > m_data; - -}; - -// disable Array for incompatible types -template -class Array; -template -class Array; - - -/// Capability container holding an array of values, -/// and default and current indexes. -/// \tparam twty ID of the internal data type. -/// \tparam DataType Exported data type. -template::Type> -class Enumeration { - - friend class Capability; - -public: - static constexpr const ConType contype = ConType::Enumeration; - typedef DataType* iterator; - typedef const DataType* const_iterator; - - /// Creates an invalid container. - constexpr Enumeration() noexcept{} - - /// ID of the internal data type. - Type type() const noexcept{ - return m_data->m_itemType; - } - - /// Number of items in the array. - UInt32 size() const noexcept{ - return m_data->m_numItems; - } - - - /// Index of the currently selected item. - UInt32 currentIndex() const noexcept{ - return m_data->m_currIndex; - } - - /// Sets index of the currently selected item. - void setCurrentIndex(UInt32 index) noexcept{ - m_data->m_currIndex = index; - } - - /// Item at the current index. - DataType& currentItem() noexcept{ - return at(m_data->m_currIndex); - } - - /// Item at the current index. - const DataType& currentItem() const noexcept{ - return at(m_data->m_currIndex); - } - - /// Sets item at the current index. - void setCurrentItem(const DataType& item) noexcept{ - currentItem() = item; - } - - - /// Index of the default item. - UInt32 defaultIndex() const noexcept{ - return m_data->m_defIndex; - } - - /// Sets index of the default item. - void setDefaultIndex(UInt32 index) noexcept{ - m_data->m_defIndex = index; - } - - /// Item at the default index. - DataType& defaultItem() noexcept{ - return at(m_data->m_defIndex); - } - - /// Item at the default index. - const DataType& defaultItem() const noexcept{ - return at(m_data->m_defIndex); - } - - /// Sets item at the default index. - void setDefaultItem(const DataType& item) noexcept{ - defaultItem() = item; - } - - - /// Access contained value in array. - DataType& at(std::size_t i) noexcept{ - return m_data->m_items[i]; - } - - /// Access contained value in array. - const DataType& at(std::size_t i) const noexcept{ - return m_data->m_items[i]; - } - - /// Sets value in array. - void set(std::size_t i, const DataType& val) noexcept{ - at(i) = val; - } - - - DataType& operator[](std::size_t i) noexcept{ - return at(i); - } - - const DataType& operator[](std::size_t i) const noexcept{ - return at(i); - } - - operator bool() const noexcept{ - return m_data; - } - - - iterator begin() noexcept{ - return m_data->m_items; - } - - const_iterator begin() const noexcept{ - return cbegin(); - } - - const_iterator cbegin() const noexcept{ - return m_data->m_items; - } - - iterator end() noexcept{ - return m_data->m_items + m_data->m_numItems; - } - - const_iterator end() const noexcept{ - return cend(); - } - - const_iterator cend() const noexcept{ - return m_data->m_items + m_data->m_numItems; - } - -private: - Enumeration(Handle h) : m_data(h){} - - Detail::Lock > m_data; - -}; - -// disable Enumeration for incompatible types -template -class Enumeration; -template -class Enumeration; - - -/// Capability container holding a range of numeric values, -/// and default and current values. -/// \tparam twty ID of the internal data type. -/// \tparam DataType Exported data type. -template::Type> -class Range { - - friend class Capability; - static_assert(Detail::IsNumeric::value, "not a numeric type"); - -private: - static constexpr const ConType contype = ConType::Range; - template - class IteratorImpl { - - friend class Range; - - public: - constexpr IteratorImpl() noexcept : - m_curr(), m_parent(nullptr){} - - IterDataType operator*() const noexcept{ - return m_curr; - } - - IteratorImpl& operator++() noexcept{ // prefix - m_curr += step(); - checkValue(); - return *this; - } - - IteratorImpl operator++(int) noexcept{ // postfix - IteratorImpl ret(*this); - m_curr += step(); - checkValue(); - return ret; - } - - IteratorImpl& operator--() noexcept{ // prefix - m_curr -= step(); - return *this; - } - - IteratorImpl operator--(int) noexcept{ // postfix - IteratorImpl ret(*this); - m_curr -= step(); - return ret; - } - - bool operator==(const IteratorImpl& o) const noexcept{ - return m_curr == o.m_curr && - (m_parent == o.m_parent || - (m_parent && o.m_parent && step() == o.step()) - ); - } - - bool operator!=(const IteratorImpl& o) const noexcept{ - return (*this == o); - } - - private: - IterDataType step() const noexcept{ - return m_parent->stepSize(); - } - - IterDataType max() const noexcept{ - return m_parent->maxValue(); - } - - void checkValue() noexcept{ - // avoid infinite loops in case no such N exists: `min + N * step == max` - if (m_curr > max()){ - m_curr = max() + step(); - } - } - - IteratorImpl(IterDataType curr, const Range& parent) noexcept : - m_curr(curr), m_parent(&parent){} - - IterDataType m_curr; - const Range* m_parent; - - }; - -public: - typedef IteratorImpl const_iterator; - - /// Creates an invalid container. - constexpr Range() noexcept{} - - /// ID of the internal data type. - Type type() const noexcept{ - return m_data->m_itemType; - } - - /// Minimal value in the range. - DataType minValue() const noexcept{ - return m_data->m_minValue; - } - - /// Sets minimal value in the range. - void setMinValue(DataType val) noexcept{ - m_data->m_minValue = val; - } - - /// Maximal value in the range. - DataType maxValue() const noexcept{ - return m_data->m_maxValue; - } - - /// Sets maximal value in the range. - void setMaxValue(DataType val) noexcept{ - m_data->m_maxValue = val; - } - - /// Size of a single step. - DataType stepSize() const noexcept{ - return m_data->m_stepSize; - } - - ///Sets size of a single step. - void setStepSize(DataType val) noexcept{ - m_data->m_stepSize = val; - } - - /// Default value in the range. - DataType defaultValue() const noexcept{ - return m_data->m_defValue; - } - - /// Sets default value in the range. - void setDefaultValue(DataType val) noexcept{ - m_data->m_defValue = val; - } - - /// Current value in the range. - DataType currentValue() const noexcept{ - return m_data->m_currValue; - } - - /// Sets current value in the range. - void setCurrentValue(DataType val) noexcept{ - m_data->m_currValue = val; - } - - operator bool() const noexcept{ - return m_data; - } - - const_iterator begin() const noexcept{ - return cbegin(); - } - - const_iterator cbegin() const noexcept{ - return const_iterator(m_data->m_minValue, *this); - } - - const_iterator end() const noexcept{ - return cend(); - } - - const_iterator cend() const noexcept{ - auto step = m_data->m_stepSize; - if (step != DataType()){ - return const_iterator(m_data->m_maxValue + step, *this); - } else { - return cbegin(); // no items with step equal to zero - } - } - -private: - Range(Handle h) : m_data(h){} - - Detail::Lock > m_data; - -}; - -// disable Range for incompatible types -// (non-numeric types) -template -class Range; -template -class Range; -template -class Range; -template -class Range; -template -class Range; -template -class Range; -template -class Range; -template -class Range; - - -namespace Detail { - -template -class CapDataImpl; - -template -class CapData; - -/// Capability iterator. -/// The default implementation is designed for non-numeric values. -/// Meaning it can't handle ranges. -template // false -class CapIterator { - - friend class Capability; - - template - friend class CapDataImpl; - -public: - constexpr CapIterator() noexcept : - m_ptr(nullptr){} - - DataType& operator*() const noexcept{ - return *m_ptr; - } - - CapIterator& operator++() noexcept{ // prefix - ++m_ptr; - return *this; - } - - CapIterator operator++(int) noexcept{ // postfix - CapIterator ret(*this); - ++m_ptr; - return ret; - } - - CapIterator& operator--() noexcept{ // prefix - --m_ptr; - return *this; - } - - CapIterator operator--(int) noexcept{ // postfix - CapIterator ret(*this); - --m_ptr; - return ret; - } - - bool operator==(const CapIterator& o) const noexcept{ - return m_ptr == o.m_ptr; - } - - bool operator!=(const CapIterator& o) const noexcept{ - return !(*this == o); - } - -private: - constexpr CapIterator(DataType* ptr) noexcept : - m_ptr(ptr){} - - DataType* m_ptr; - -}; - -/// Capability iterator. -/// This specialization can handles numeric values only. -/// Ranges included. -template -class CapIterator { - - friend class Capability; - - template - friend class CapDataImpl; - -public: - typedef typename std::remove_const::type ReturnType; - - constexpr CapIterator() noexcept : - m_ptr(nullptr), m_isPtr(true){} - - ReturnType operator*() const noexcept{ - if (m_isPtr){ - return *m_ptr; - } else { - return *m_rng; - } - } - - CapIterator& operator++() noexcept{ // prefix - if (m_isPtr){ - ++m_ptr; - } else { - ++m_rng; - } - - return *this; - } - - CapIterator operator++(int) noexcept{ // postfix - CapIterator ret(*this); - if (m_isPtr){ - ++m_ptr; - } else { - ++m_rng; - } - - return ret; - } - - CapIterator& operator--() noexcept{ // prefix - if (m_isPtr){ - --m_ptr; - } else { - --m_rng; - } - - return *this; - } - - CapIterator operator--(int) noexcept{ // postfix - CapIterator ret(*this); - if (m_isPtr){ - --m_ptr; - } else { - --m_rng; - } - - return ret; - } - - bool operator==(const CapIterator& o) const noexcept{ - if (m_isPtr != o.m_isPtr){ - return false; - } - - return m_isPtr ? m_ptr == o.m_ptr : m_rng == o.m_rng; - } - - bool operator!=(const CapIterator& o) const noexcept{ - return !(*this == o); - } - -private: - constexpr CapIterator(DataType* ptr) noexcept : - m_ptr(ptr), m_isPtr(true){} - - constexpr CapIterator(typename Range::const_iterator rng) noexcept : - m_rng(rng), m_isPtr(false){} - - union { - DataType* m_ptr; - typename Range::const_iterator m_rng; - }; - bool m_isPtr; - -}; - -/// Capability iterator lock implementation. -/// The default implementation is designed for non-numeric values. -/// Meaning it can't handle ranges. -template::Type> // numeric=false -class CapDataImpl { - - friend class Capability; - - template - friend class CapData; - -public: - typedef CapIterator const_iterator; - - /// Creates an invalid container. - constexpr CapDataImpl() noexcept : - m_data(){ - - static_assert(type != Type::DontCare, "type may not be DontCare"); - static_assert(sizeof(typename Detail::Twty::Type) == sizeof(DataType), "type sizes dont match"); - } - - const_iterator begin() const noexcept{ - return cbegin(); - } - - const_iterator cbegin() const noexcept{ - return const_iterator(reinterpret_cast(m_data.data() + offset())); - } - - const_iterator end() const noexcept{ - return cend(); - } - - const_iterator cend() const noexcept{ - return const_iterator(reinterpret_cast(m_data.data() + offset()) + size()); - } - - UInt32 size() const noexcept{ - switch (m_conType){ - case ConType::Array: - case ConType::Enumeration: - return reinterpret_cast*>(m_data.data())->m_numItems; - case ConType::OneValue: - return 1; - case ConType::Range: - default: - return 0; // should not happen - } - } - -private: - CapDataImpl(const Capability& cap); - - UInt32 offset() const noexcept{ - switch (m_conType){ - case ConType::Array: - return sizeof(Type) + sizeof(UInt32); - case ConType::Enumeration: - return sizeof(Type) + 3 * sizeof(UInt32); - case ConType::OneValue: - return sizeof(Type); - case ConType::Range: - default: - return 0; // should not happen - } - } - - ConType m_conType; - Detail::Lock m_data; // actual type resolved at runtime - -}; - -/// Capability iterator lock implementation. -/// This specialization can handles numeric values only. -/// Ranges included. -template -class CapDataImpl { - - friend class Capability; - - template - friend class CapData; - -public: - typedef CapIterator const_iterator; - - /// Creates an invalid container. - constexpr CapDataImpl() noexcept : - m_data(){ - - static_assert(type != Type::DontCare, "type may not be DontCare"); - static_assert(sizeof(typename Detail::Twty::Type) == sizeof(DataType), "type sizes dont match"); - } - - const_iterator begin() const noexcept{ - return cbegin(); - } - - const_iterator cbegin() const noexcept{ - if (m_conType != ConType::Range){ - return const_iterator(reinterpret_cast(m_data.data() + offset())); - } else { - const auto& rng = *Detail::alias_cast*>(&m_data); - return const_iterator(rng.cbegin()); - } - } - - const_iterator end() const noexcept{ - return cend(); - } - - const_iterator cend() const noexcept{ - if (m_conType != ConType::Range){ - return const_iterator(reinterpret_cast(m_data.data() + offset()) + size()); - } else { - const auto& rng = *Detail::alias_cast*>(&m_data); - return const_iterator(rng.cend()); - } - } - - UInt32 size() const noexcept{ - switch (m_conType){ - case ConType::Array: - case ConType::Enumeration: - return reinterpret_cast*>(m_data.data())->m_numItems; - case ConType::OneValue: - return 1; - case ConType::Range: { - auto& rng = *reinterpret_cast*>(m_data.data()); - if (rng.m_stepSize != DataType()){ - return static_cast((Detail::abs(rng.m_maxValue - rng.m_minValue) / rng.m_stepSize).toFloat()) + 1; - } else { - return 0; - } - } - default: - return 0; // should not happen - } - } - -private: - CapDataImpl(const Capability& cap); - - UInt32 offset() const noexcept{ - switch (m_conType){ - case ConType::Array: - return sizeof(Type) + sizeof(UInt32); - case ConType::Enumeration: - return sizeof(Type) + 3 * sizeof(UInt32); - case ConType::OneValue: - return sizeof(Type); - case ConType::Range: - default: - return 0; // should not happen - } - } - - ConType m_conType; - Detail::Lock m_data; // actual type resolved at runtime - -}; - -/// Capability iterator lock. -template -class CapData : public CapDataImpl::value, DataType> { - - typedef CapDataImpl::value, DataType> Base; - -public: - constexpr CapData() noexcept{} - - CapData(const Capability& cap) : - Base(cap){} - -}; - - -/// Capability current item implementation. -/// The default implementation is designed for non-numeric values. -/// Meaning it can't handle ranges. -template // false -struct CurrentItemImpl { - static DataType item(Capability& cap); -}; - -/// Capability current item implementation. -/// This specialization can handles numeric values only. -/// Ranges included. -template -struct CurrentItemImpl { - static DataType item(Capability& cap); -}; - -/// Capability current item. -template -struct CurrentItem : CurrentItemImpl::value> { - -}; - -} - -/// Base capability exception. -class CapabilityException : public Exception { - -public: - virtual const char* what() const noexcept override{ - return "Capability handling error."; - } - -}; - -/// Invalid or unsupported container capability exception. -class ContainerException : public CapabilityException { - -public: - virtual const char* what() const noexcept override{ - return "Unexpected container."; - } - -}; - -/// Invalid, unsupported or mismatched item type identifier capability exception. -class ItemTypeException : public CapabilityException { - -public: - virtual const char* what() const noexcept override{ - return "Invalid item type."; - } - -}; - -/// No data capability exception. -/// Capability does not contain any data (container). -class DataException : public CapabilityException { - -public: - virtual const char* what() const noexcept override{ - return "No data."; - } - -}; - -TWPP_DETAIL_PACK_BEGIN -/// TWAIN capability. -/// Any access to containers must be finished before destroying -/// the according capability instance. -class Capability { - - template - friend class Detail::CapDataImpl; - -public: - /// Creates capability holding OneValue container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \param cap Capability type. - /// \param value Initial value. - /// \throw std::bad_alloc - template - static Capability createOneValue(CapType cap, const DataType& value = DataType()){ - Capability ret(cap, ConType::OneValue, type, sizeof(Detail::OneValueData)); - auto ov = ret.oneValue(); - ov.setItem(value); - return std::move(ret); - } - - /// Creates capability holding OneValue container. - /// \tparam type ID of the internal data type. - /// \param cap Capability type. - /// \param value Initial value. - /// \throw std::bad_alloc - template - static Capability createOneValue(CapType cap, const typename Detail::Twty::Type& value = typename Detail::Twty::Type()){ - return createOneValue::Type>(cap, value); - } - - /// Creates capability holding OneValue container. - /// \tparam T Data type. - /// \param cap Capability type. - /// \param value Initial value. - /// \throw std::bad_alloc - template - static Capability createOneValue(CapType cap, const T& value = T()){ - return createOneValue::twty, T>(cap, value); - } - - /// Creates capability holding OneValue container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \param value Initial value. - /// \throw std::bad_alloc - template - static Capability createOneValue(const typename Detail::Cap::DataType& value = typename Detail::Cap::DataType()){ - return createOneValue::twty, typename Detail::Cap::DataType>(cap, value); - } - - - /// Creates capability holding Array container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \param cap Capability type. - /// \param size Number of elements in the array. - /// \throw std::bad_alloc - template - static Capability createArray(CapType cap, UInt32 size){ - Capability ret(cap, ConType::Array, type, sizeof(Detail::ArrayData) - sizeof(DataType) + size * sizeof(DataType)); - auto arr = ret.array(); - arr.m_data->m_numItems = size; - return std::move(ret); - } - - /// Creates capability holding Array container. - /// \tparam type ID of the internal data type. - /// \param cap Capability type. - /// \param size Number of elements in the array. - /// \throw std::bad_alloc - template - static Capability createArray(CapType cap, UInt32 size){ - return createArray::Type>(cap, size); - } - - /// Creates capability holding Array container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \param cap Capability type. - /// \param values Initial values in the array. - /// \throw std::bad_alloc - template - static Capability createArray(CapType cap, std::initializer_list values){ - Capability ret = createArray(cap, static_cast(values.size())); - auto arr = ret.array(); - - UInt32 i = 0; - for (const auto& val : values){ - arr[i] = val; - i++; - } - - return std::move(ret); - } - - /// Creates capability holding Array container. - /// \tparam type ID of the internal data type. - /// \param cap Capability type. - /// \param values Initial values in the array. - /// \throw std::bad_alloc - template - static Capability createArray(CapType cap, std::initializer_list::Type> values){ - return createArray::Type>(cap, values); - } - - /// Creates capability holding Array container. - /// \tparam T Data type. - /// \param cap Capability type. - /// \param size Number of elements in the array. - /// \throw std::bad_alloc - template - static Capability createArray(CapType cap, UInt32 size){ - return createArray::twty, T>(cap, size); - } - - /// Creates capability holding Array container. - /// \tparam T Data type. - /// \param cap Capability type. - /// \param values Initial values in the array. - /// \throw std::bad_alloc - template - static Capability createArray(CapType cap, std::initializer_list values){ - return createArray::twty, T>(cap, values); - } - - /// Creates capability holding Array container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \param size Number of elements in the array. - /// \throw std::bad_alloc - template - static Capability createArray(UInt32 size){ - return createArray::twty, typename Detail::Cap::DataType>(cap, size); - } - - /// Creates capability holding Array container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \param values Initial values in the array. - /// \throw std::bad_alloc - template - static Capability createArray(std::initializer_list::DataType> values){ - return createArray::twty, typename Detail::Cap::DataType>(cap, values); - } - - - /// Creates capability holding Enumeration container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \param cap Capability type. - /// \param size Number of elements in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - template - static Capability createEnumeration(CapType cap, UInt32 size, UInt32 currIndex = 0, UInt32 defIndex = 0){ - Capability ret(cap, ConType::Enumeration, type, sizeof(Detail::EnumerationData) - sizeof(DataType) + size * sizeof(DataType)); - auto enm = ret.enumeration(); - enm.m_data->m_numItems = size; - enm.m_data->m_currIndex = currIndex; - enm.m_data->m_defIndex = defIndex; - return std::move(ret); - } - - /// Creates capability holding Enumeration container. - /// \tparam type ID of the internal data type. - /// \param cap Capability type. - /// \param size Number of elements in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - template - static Capability createEnumeration(CapType cap, UInt32 size, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return createEnumeration::Type>(cap, size, currIndex, defIndex); - } - - /// Creates capability holding Enumeration container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \param cap Capability type. - /// \param values Initial values in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - template - static Capability createEnumeration(CapType cap, std::initializer_list values, UInt32 currIndex = 0, UInt32 defIndex = 0){ - Capability ret = createEnumeration(cap, static_cast(values.size()), currIndex, defIndex); - auto enm = ret.enumeration(); - - UInt32 i = 0; - for (const auto& val : values){ - enm[i] = val; - i++; - } - - return std::move(ret); - } - template - static Capability createEnumeration(CapType cap, std::list values, UInt32 currIndex = 0, UInt32 defIndex = 0){ - Capability ret = createEnumeration(cap, static_cast(values.size()), currIndex, defIndex); - auto enm = ret.enumeration(); - - UInt32 i = 0; - for (const auto& val : values){ - enm[i] = val; - i++; - } - - return std::move(ret); - } - - /// Creates capability holding Enumeration container. - /// \tparam type ID of the internal data type. - /// \param cap Capability type. - /// \param values Initial values in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - template - static Capability createEnumeration(CapType cap, std::initializer_list::Type> values, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return createEnumeration::Type>(cap, values, currIndex, defIndex); - } - - /// Creates capability holding Enumeration container. - /// \tparam T Data type. - /// \param cap Capability type. - /// \param size Number of elements in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - template - static Capability createEnumeration(CapType cap, UInt32 size, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return createEnumeration::twty, T>(cap, size, currIndex, defIndex); - } - - /// Creates capability holding Enumeration container. - /// \tparam T Data type. - /// \param cap Capability type. - /// \param values Initial values in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - template - static Capability createEnumeration(CapType cap, std::initializer_list values, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return createEnumeration::twty, T>(cap, values, currIndex, defIndex); - } - template - static Capability createEnumeration(CapType cap, std::list values, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return createEnumeration::twty, T>(cap, values, currIndex, defIndex); - } - - /// Creates capability holding Enumeration container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \param size Number of elements in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - template - static Capability createEnumeration(UInt32 size, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return createEnumeration::twty, typename Detail::Cap::DataType>(cap, size, currIndex, defIndex); - } - - /// Creates capability holding Enumeration container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \param values Initial values in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - template - static Capability createEnumeration(std::initializer_list::DataType> values, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return createEnumeration::twty, typename Detail::Cap::DataType>(cap, values, currIndex, defIndex); - } - template - static Capability createEnumeration(std::list::DataType> values, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return createEnumeration::twty, typename Detail::Cap::DataType>(cap, values, currIndex, defIndex); - } - - - /// Creates capability holding Range container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \param cap Capability type. - /// \param min Minimal range value. - /// \param max Maximal range value. - /// \param step Size of a single step. - /// \param curr Current value. - /// \param def Default value. - /// \throw std::bad_alloc - template - static Capability createRange(CapType cap, DataType min, DataType max, DataType step, DataType curr, DataType def){ - Capability ret(cap, ConType::Range, type, sizeof(Detail::RangeData)); - auto rng = ret.range(); - rng.setMinValue(min); - rng.setMaxValue(max); - rng.setStepSize(step); - rng.setCurrentValue(curr); - rng.setDefaultValue(def); - return std::move(ret); - } - - /// Creates capability holding Range container. - /// \tparam type ID of the internal data type. - /// \param cap Capability type. - /// \param min Minimal range value. - /// \param max Maximal range value. - /// \param step Size of a single step. - /// \param curr Current value. - /// \param def Default value. - /// \throw std::bad_alloc - template - static Capability createRange( - CapType cap, - typename Detail::Twty::Type min, - typename Detail::Twty::Type max, - typename Detail::Twty::Type step, - typename Detail::Twty::Type curr, - typename Detail::Twty::Type def - ){ - return createRange::Type>(cap, min, max, step, curr, def); - } - - /// Creates capability holding Range container. - /// \tparam T Data type. - /// \param cap Capability type. - /// \param min Minimal range value. - /// \param max Maximal range value. - /// \param step Size of a single step. - /// \param curr Current value. - /// \param def Default value. - /// \throw std::bad_alloc - template - static Capability createRange(CapType cap, T min, T max, T step, T curr, T def){ - return createRange::twty, T>(cap, min, max, step, curr, def); - } - - /// Creates capability holding Range container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \param min Minimal range value. - /// \param max Maximal range value. - /// \param step Size of a single step. - /// \param curr Current value. - /// \param def Default value. - /// \throw std::bad_alloc - template - static Capability createRange( - typename Detail::Cap::DataType min, - typename Detail::Cap::DataType max, - typename Detail::Cap::DataType step, - typename Detail::Cap::DataType curr, - typename Detail::Cap::DataType def - ){ - return createRange::twty, typename Detail::Cap::DataType>( - cap, min, max, step, curr, def); - } - - - /// Creates capability of the supplied type without any data. - /// Useful for retrieving data from data source. - explicit Capability(CapType cap) noexcept : - m_cap(cap), m_conType(ConType::DontCare), m_cont(){} - - Capability(Capability&&) = default; - Capability& operator=(Capability&&) = default; - - /// Capability type. - CapType type() const noexcept{ - return m_cap; - } - - /// dangerous set CapType - void dangerous_set_cap(CapType cap) { - m_cap = cap; - } - - /// Container type. - ConType container() const noexcept{ - return m_conType; - } - - /// Item type. - /// Valid only if the capability contains data. - /// \throw DataException When there is no data. - Type itemType() const{ - if (!m_cont){ - throw DataException(); - } - - return *m_cont.lock().data(); - } - - operator bool() const noexcept{ - return m_cont; - } - - /// Contained OneValue container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not OneValue. - /// \throw ItemTypeException When item type does not match. - template - OneValue oneValue(){ - return containerCheck(); - } - - /// Contained OneValue container. - /// \tparam type ID of the internal data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not OneValue. - /// \throw ItemTypeException When item type does not match. - template - OneValue::Type> oneValue(){ - return oneValue::Type>(); - } - - /// Contained OneValue container. - /// \tparam T Data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not OneValue. - /// \throw ItemTypeException When item type does not match. - template - OneValue::twty, T> oneValue(){ - return oneValue::twty, T>(); - } - - /// Contained OneValue container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not OneValue. - /// \throw ItemTypeException When item type does not match. - template - OneValue::twty, typename Detail::Cap::DataType> oneValue(){ - return oneValue::twty, typename Detail::Cap::DataType>(); - } - - /// Contained Array container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Array. - /// \throw ItemTypeException When item type does not match. - template - Array array(){ - return containerCheck(); - } - - /// Contained Array container. - /// \tparam type ID of the internal data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Array. - /// \throw ItemTypeException When item type does not match. - template - Array::Type> array(){ - return array::Type>(); - } - - /// Contained Array container. - /// \tparam T Data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Array. - /// \throw ItemTypeException When item type does not match. - template - Array::twty, T> array(){ - return array::twty, T>(); - } - - /// Contained Array container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Array. - /// \throw ItemTypeException When item type does not match. - template - Array::twty, typename Detail::Cap::DataType> array(){ - return array::twty, typename Detail::Cap::DataType>(); - } - - /// Contained Enumeration container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration. - /// \throw ItemTypeException When item type does not match. - template - Enumeration enumeration(){ - return containerCheck(); - } - - /// Contained Enumeration container. - /// \tparam type ID of the internal data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration. - /// \throw ItemTypeException When item type does not match. - template - Enumeration::Type> enumeration(){ - return enumeration::Type>(); - } - - /// Contained Enumeration container. - /// \tparam T Data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration. - /// \throw ItemTypeException When item type does not match. - template - Enumeration::twty, T> enumeration(){ - return enumeration::twty, T>(); - } - - /// Contained Enumeration container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration. - /// \throw ItemTypeException When item type does not match. - template - Enumeration::twty, typename Detail::Cap::DataType> enumeration(){ - return enumeration::twty, typename Detail::Cap::DataType>(); - } - - /// Contained Range container. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration. - /// \throw ItemTypeException When item type does not match. - template - Range range(){ - return containerCheck(); - } - - /// Contained Range container. - /// \tparam type ID of the internal data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration. - /// \throw ItemTypeException When item type does not match. - template - Range::Type> range(){ - return range::Type>(); - } - - /// Contained Range container. - /// \tparam T Data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Range. - /// \throw ItemTypeException When item type does not match. - template - Range::twty, T> range(){ - return range::twty, T>(); - } - - /// Contained Range container. - /// \tparam cap Capability type. Data types are set accordingly. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Range. - /// \throw ItemTypeException When item type does not match. - template - Range::twty, typename Detail::Cap::DataType> range(){ - return range::twty, typename Detail::Cap::DataType>(); - } - - template - using Data = Detail::CapData; - - /// Returns a data container for iterating over all possible values. - /// Use this only if you don't care about current or default values and container type. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is invalid. - /// \throw ItemTypeException When item type does not match. - template - Data data() const{ - return *this; - } - - /// Returns a data container for iterating over all possible values. - /// Use this only if you don't care about current or default values and container type. - /// \tparam type ID of the internal data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is invalid. - /// \throw ItemTypeException When item type does not match. - template - Data::Type> data() const{ - return *this; - } - - /// Returns a data container for iterating over all possible values. - /// Use this only if you don't care about current or default values and container type. - /// \tparam T Data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is invalid. - /// \throw ItemTypeException When item type does not match. - template - Data::twty, T> data() const{ - return *this; - } - - /// Returns a data container for iterating over all possible values. - /// Use this only if you don't care about current or default values and container type. - /// \tparam cap Capability type. Data types are set accordingly. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is invalid. - /// \throw ItemTypeException When item type does not match. - template - Data::twty, typename Detail::Cap::DataType> data() const{ - return *this; - } - - - /// Returns a copy of the current item of this capability. - /// Can be used only with Enumeration, OneValue, and Range containers. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration, OneValue, nor Range. - /// \throw ItemTypeException When item type does not match. - template - DataType currentItem(){ - return Detail::CurrentItem::item(*this); - } - - /// Returns a copy of the current item of this capability. - /// Can be used only with Enumeration, OneValue, and Range containers. - /// \tparam type ID of the internal data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration, OneValue, nor Range. - /// \throw ItemTypeException When item type does not match. - template - typename Detail::Twty::Type currentItem(){ - return currentItem::Type>(); - } - - /// Returns a copy of the current item of this capability. - /// Can be used only with Enumeration, OneValue, and Range containers. - /// \tparam T Data type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration, OneValue, nor Range. - /// \throw ItemTypeException When item type does not match. - template - T currentItem(){ - return currentItem::twty, T>(); - } - - /// Returns a copy of the current item of this capability. - /// Can be used only with Enumeration, OneValue, and Range containers. - /// \tparam cap Capability type. Data types are set accordingly. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration, OneValue, nor Range. - /// \throw ItemTypeException When item type does not match. - template - typename Detail::Cap::DataType currentItem(){ - return currentItem::twty, typename Detail::Cap::DataType>(); - } - -private: - /// \throw DataException - /// \throw ContainerException - /// \throw ItemTypeException - Capability(CapType cap, ConType conType, Type twty, UInt32 size) : - m_cap(cap), m_conType(conType), m_cont(Detail::alloc(size)){ - - *m_cont.lock().data() = twty; - } - - template class Container, Type type, typename DataType> - Container containerCheck(){ - static_assert(type != Type::DontCare, "type may not be DontCare"); - static_assert(sizeof(typename Detail::Twty::Type) == sizeof(DataType), "type sizes dont match"); - - if (!m_cont){ - throw DataException(); - } - - if (Container::contype != container()){ - throw ContainerException(); - } - - Container ret(m_cont.get()); - UINT16 r_type = (UINT16)ret.type(); - UINT16 m_type = (UINT16)type; - if (!((((r_type >= 0) || (r_type <= 5)) && ((m_type >= 0) || (m_type <= 5))) || (((r_type >= 9) || (r_type <= 12)) && ((m_type >= 9) || (m_type <= 12))) || (m_type == r_type))) { - //if (type != r_type){ - throw ItemTypeException(); - } - - return std::move(ret); - } - - CapType m_cap; - ConType m_conType; - Detail::UniqueHandle m_cont; - -}; -TWPP_DETAIL_PACK_END - -/// Invalid, unsupported or mismatched item type identifier capability exception. -/// Holds the Capability instance that caused the exception. -class CapItemTypeException : public ItemTypeException { - -public: - CapItemTypeException(Capability cap) noexcept : - m_cap(std::move(cap)){} - - CapItemTypeException(CapItemTypeException&&) = default; - CapItemTypeException& operator=(CapItemTypeException&&) = default; - - CapItemTypeException(const CapItemTypeException&) = delete; - CapItemTypeException& operator=(const CapItemTypeException&) = delete; - - Capability& capability() noexcept{ - return m_cap; - } - - const Capability& capability() const noexcept{ - return m_cap; - } - - virtual const char* what() const noexcept override{ - return "Unexpected item type."; - } - -private: - Capability m_cap; - -}; - -/// Invalid, unexpected, unmatched capability type. -/// Holds the Capability instance that caused the exception. -class CapTypeException : public CapabilityException { - -public: - CapTypeException(Capability cap) noexcept : - m_cap(std::move(cap)){} - - CapTypeException(CapTypeException&&) = default; - CapTypeException& operator=(CapTypeException&&) = default; - - CapTypeException(const CapTypeException&) = delete; - CapTypeException& operator=(const CapTypeException&) = delete; - - Capability& capability() noexcept{ - return m_cap; - } - - const Capability& capability() const noexcept{ - return m_cap; - } - - virtual const char* what() const noexcept override{ - return "Unexpected capability type."; - } - -private: - Capability m_cap; - -}; - -class Source; - -/// Convenience Capability wrapper class. -/// Guaranteed to contain the same capability type and item type -/// throughout the whole lifetime. -template -class Cap { - - friend class Source; - -public: - typedef typename Detail::Cap::DataType DataType; - static constexpr const Type twty = Detail::Cap::twty; - - /// Creates capability holding OneValue container. - /// \param value Initial value. - /// \throw std::bad_alloc - static Cap createOneValue(const DataType& value = DataType()){ - return Cap(Capability::createOneValue(value), 0); - } - - - /// Creates capability holding Array container. - /// \param size Number of elements in the array. - /// \throw std::bad_alloc - static Cap createArray(UInt32 size){ - return Cap(Capability::createArray(size), 0); - } - - /// Creates capability holding Array container. - /// \param values Initial values in the array. - /// \throw std::bad_alloc - static Cap createArray(std::initializer_list values){ - return Cap(Capability::createArray(values), 0); - } - - - /// Creates capability holding Enumeration container. - /// \param size Number of elements in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - static Cap createEnumeration(UInt32 size, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return Cap(Capability::createEnumeration(size, currIndex, defIndex), 0); - } - - /// Creates capability holding Enumeration container. - /// \param values Initial values in the array. - /// \param currIndex Index of the currently selected item. - /// \param defIndex Index of the default item. - /// \throw std::bad_alloc - static Cap createEnumeration(std::initializer_list values, UInt32 currIndex = 0, UInt32 defIndex = 0){ - return Cap(Capability::createEnumeration(values, currIndex, defIndex), 0); - } - - - /// Creates capability holding Range container. - /// \param min Minimal range value. - /// \param max Maximal range value. - /// \param step Size of a single step. - /// \param curr Current value. - /// \param def Default value. - /// \throw std::bad_alloc - static Cap createRange(DataType min, DataType max, DataType step, DataType curr, DataType def){ - return Cap(Capability::createRange(min, max, step, curr, def), 0); - } - - /// Creates capability of the supplied type without any data. - /// Useful for retrieving data from data source. - Cap() noexcept : m_cap(cap){} - - /// Converts Capability to Cap. - /// The capability ownership is taken over. - /// Capability type and item type checkings are performed. In case of exception, - /// the original Capability instance may be retrieved from the exception object. - /// \param capability Capability to be converted to Cap. - /// \throw CapTypeException When input capability type does not match the - /// capability type of this template class. - /// \throw CapItemTypeException When input capability item type does not match - /// the expected item type of the capability. - explicit Cap(Capability capability) : - m_cap(std::move(capability)){ - - checkTypes(); - } - - Cap(Cap&&) = default; - Cap& operator=(Cap&&) = default; - - Cap(const Cap&) = delete; - Cap& operator=(const Cap&) = delete; - - /// Capability type. - CapType type() const noexcept{ - return m_cap.type(); - } - - /// Container type. - ConType container() const noexcept{ - return m_cap.container(); - } - - /// Item type. - /// Valid only if the capability contains data. - /// \throw DataException When there is no data. - Type itemType() const{ - return m_cap.itemType(); - } - - operator bool() const noexcept{ - return m_cap; - } - - /// Contained OneValue container. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not OneValue. - /// \throw ItemTypeException When item type does not match. - OneValue oneValue(){ - return m_cap.oneValue(); - } - - /// Contained Array container. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Array. - /// \throw ItemTypeException When item type does not match. - Array array(){ - return m_cap.array(); - } - - /// Contained Enumeration container. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration. - /// \throw ItemTypeException When item type does not match. - Enumeration enumeration(){ - return m_cap.enumeration(); - } - - /// Contained Range container. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration. - /// \throw ItemTypeException When item type does not match. - Range range(){ - return m_cap.range(); - } - - - typedef Detail::CapData Data; - - /// Returns a data container for iterating over all possible values. - /// Use this only if you don't care about current or default values and container type. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is invalid. - /// \throw ItemTypeException When item type does not match. - Data data() const{ - return m_cap.data(); - } - - - /// Returns a copy of the current item of this capability. - /// Can be used only with Enumeration, OneValue, and Range containers. - /// \throw DataException When there is no data. - /// \throw ContainerException When container is not Enumeration, OneValue, nor Range. - /// \throw ItemTypeException When item type does not match. - DataType currentItem(){ - return m_cap.currentItem(); - } - - /// Moves out the contained Capability instance. - /// This instance becomes empty. - Capability toCapability() noexcept{ - return std::move(m_cap); - } - -private: - Cap(Capability capability, int) noexcept : - m_cap(std::move(capability)){} - - void checkTypes(){ - if (m_cap){ - if (m_cap.type() != cap){ - throw CapTypeException(std::move(m_cap)); - } - - if (m_cap.itemType() != twty){ - throw CapItemTypeException(std::move(m_cap)); - } - } - } - - Capability m_cap; - -}; - - -namespace Detail { - -/// \throw DataException -/// \throw ContainerException -/// \throw ItemTypeException -template // numeric = false -inline CapDataImpl::CapDataImpl(const Capability& cap) : - m_conType(cap.m_conType), m_data(cap.m_cont.get()){ - - static_assert(type != Type::DontCare, "type may not be DontCare"); - static_assert(sizeof(typename Detail::Twty::Type) == sizeof(DataType), "type sizes dont match"); - - if (!cap.m_cont){ - throw DataException(); - } - - switch (m_conType){ - case ConType::Array: - case ConType::Enumeration: - case ConType::OneValue: - break; - case ConType::Range: - default: - throw ContainerException(); - } - - if (type != cap.itemType()){ - throw ItemTypeException(); - } -} - -/// \throw DataException -/// \throw ContainerException -/// \throw ItemTypeException -template -inline CapDataImpl::CapDataImpl(const Capability& cap) : - m_conType(cap.m_conType), m_data(cap.m_cont.get()){ - - static_assert(type != Type::DontCare, "type may not be DontCare"); - static_assert(sizeof(typename Detail::Twty::Type) == sizeof(DataType), "type sizes dont match"); - - if (!cap.m_cont){ - throw DataException(); - } - - switch (m_conType){ - case ConType::Array: - case ConType::Enumeration: - case ConType::OneValue: - case ConType::Range: - break; - default: - throw ContainerException(); - } - - if (type != cap.itemType()){ - throw ItemTypeException(); - } -} - -/// \throw DataException -/// \throw ContainerException -/// \throw ItemTypeException -template // false -DataType CurrentItemImpl::item(Capability& cap){ - switch (cap.container()){ - case ConType::Enumeration: - return cap.enumeration().currentItem(); - - case ConType::OneValue: - return cap.oneValue().item(); - - default: - throw ContainerException(); - } -} - -/// \throw DataException -/// \throw ContainerException -/// \throw ItemTypeException -template -DataType CurrentItemImpl::item(Capability& cap){ - switch (cap.container()){ - case ConType::Enumeration: - return cap.enumeration().currentItem(); - - case ConType::OneValue: - return cap.oneValue().item(); - - case ConType::Range: - return cap.range().currentValue(); - - default: - throw ContainerException(); - } -} - -} - -} - -#endif // TWPP_DETAIL_FILE_CAPABILITY_HPP - diff --git a/twain/twain/twpp/cie.hpp b/twain/twain/twpp/cie.hpp deleted file mode 100644 index 2a1f641..0000000 --- a/twain/twain/twpp/cie.hpp +++ /dev/null @@ -1,269 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_CIE_HPP -#define TWPP_DETAIL_FILE_CIE_HPP - -#if 0 -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Part of CieColor structure. -class CiePoint { - -public: - /// Creates zero-initialized cie point. - constexpr CiePoint() noexcept : - m_x(), m_y(), m_z(){} - - /// Creates cie point with desired values. - constexpr CiePoint(Fix32 x, Fix32 y, Fix32 z) noexcept : - m_x(x), m_y(y), m_z(z){} - - /// X value of CIE space. - constexpr Fix32 x() const noexcept{ - return m_x; - } - - /// Y value of CIE space. - constexpr Fix32 y() const noexcept{ - return m_y; - } - - /// Z value of CIE space. - constexpr Fix32 z() const noexcept{ - return m_z; - } - - /// Sets x value of CIE space. - void setX(Fix32 x) noexcept{ - m_x = x; - } - - /// Sets y value of CIE space. - void setY(Fix32 y) noexcept{ - m_y = y; - } - - /// Sets z value of CIE space. - void setZ(Fix32 z) noexcept{ - m_z = z; - } - -private: - Fix32 m_x; - Fix32 m_y; - Fix32 m_z; - -}; - -/// Defines parameters for channel transformations. -/// Part of TransformStage. -class DecodeFunction { - -public: - /// Creates zero-initialized decode function. - constexpr DecodeFunction() noexcept{} - - /// Creates initialized decode function. - constexpr DecodeFunction( - Fix32 startIn, - Fix32 breakIn, - Fix32 endIn, - Fix32 startOut, - Fix32 breakOut, - Fix32 endOut, - Fix32 gamma, - Fix32 sampleCount - ) noexcept : - m_startIn(startIn), m_breakIn(breakIn), m_endIn(endIn), - m_startOut(startOut), m_breakOut(breakOut), m_endOut(endOut), - m_gamma(gamma), m_sampleCount(sampleCount){} - - /// Starting input value. - constexpr Fix32 startIn() const noexcept{ - return m_startIn; - } - - /// Sets starting input value. - void setStartIn(Fix32 startIn) noexcept{ - m_startIn = startIn; - } - - /// Ending input value. - constexpr Fix32 breakIn() const noexcept{ - return m_breakIn; - } - - /// Sets ending input value. - void setBreakIn(Fix32 breakIn) noexcept{ - m_breakIn = breakIn; - } - - /// Input value when to switch from linear to gamma transformation. - constexpr Fix32 endIn() const noexcept{ - return m_endIn; - } - - /// Sets input value when to switch from linear to gamma transformation. - void setEndIn(Fix32 endIn) noexcept{ - m_endIn = endIn; - } - - /// Starting output value. - constexpr Fix32 startOut() const noexcept{ - return m_startOut; - } - - /// Sets starting output value. - void setStartOut(Fix32 startOut) noexcept{ - m_startOut = startOut; - } - - /// Ending output value. - constexpr Fix32 breakOut() const noexcept{ - return m_breakOut; - } - - /// Sets ending output value. - void setBreakOut(Fix32 breakOut) noexcept{ - m_breakOut = breakOut; - } - - /// Output value when to switch from linear to gamma transformation. - constexpr Fix32 endOut() const noexcept{ - return m_endOut; - } - - /// Sets output value when to switch from linear to gamma transformation. - void setEndOut(Fix32 endOut) noexcept{ - m_endOut = endOut; - } - - /// Constant, exponential used in gamma funciton. - constexpr Fix32 gamma() const noexcept{ - return m_gamma; - } - - /// Sets constant, exponential used in gamma funciton. - void setGamma(Fix32 gamma) noexcept{ - m_gamma = gamma; - } - - /// Number of samples in lookup table. - constexpr Fix32 sampleCount() const noexcept{ - return m_sampleCount; - } - - /// Sets number of samples in lookup table. - void setSampleCount(Fix32 sampleCount) noexcept{ - m_sampleCount = sampleCount; - } - -private: - Fix32 m_startIn; - Fix32 m_breakIn; - Fix32 m_endIn; - Fix32 m_startOut; - Fix32 m_breakOut; - Fix32 m_endOut; - Fix32 m_gamma; - Fix32 m_sampleCount; - -}; - -/// Parameters of ABC or LMN transformations. -/// Refer to manual for more information about members. -class TransformStage { - -public: - typedef std::array Decode; - typedef std::array, 3> Mix; - - constexpr TransformStage() noexcept : - m_decode(), m_mix(){} - - constexpr TransformStage(const Decode& decode) noexcept : - m_decode(decode), m_mix(){} - - constexpr TransformStage(const Mix& mix) noexcept : - m_decode(), m_mix(mix){} - - constexpr TransformStage(const Decode& decode, const Mix& mix) noexcept : - m_decode(decode), m_mix(mix){} - - constexpr const Decode& decode() const noexcept{ - return m_decode; - } - - Decode& decode() noexcept{ - return m_decode; - } - - constexpr const Mix& mix() const noexcept{ - return m_mix; - } - - Mix& mix() noexcept{ - return m_mix; - } - -private: - Decode m_decode; - Mix m_mix; - -}; - -namespace Unsupported { - -// TODO CieColor -/// Cie color -/// Currently stub, more info required. -struct CieColor { - UInt16 m_colorSpace; - Bool m_lowEndian; - Bool m_deviceDependent; - Int32 m_versionNumber; - TransformStage m_stageAbc; - TransformStage m_stageLmn; - CiePoint m_whitePoint; - CiePoint m_blackPoint; - CiePoint m_whitePaper; - CiePoint m_blackInk; - Fix32 m_samples[1]; // <- how many elements? how to use? -}; - -} - -TWPP_DETAIL_PACK_END - -} -#endif - -#endif // TWPP_DETAIL_FILE_CIE_HPP - diff --git a/twain/twain/twpp/curveresponse.hpp b/twain/twain/twpp/curveresponse.hpp deleted file mode 100644 index e5d71f7..0000000 --- a/twain/twain/twpp/curveresponse.hpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_CURVERESPONSE_HPP -#define TWPP_DETAIL_FILE_CURVERESPONSE_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -/// Base response class. -class CurveResponse { - -public: - CurveResponse() noexcept{} - - /// Creates a new (Rgb|Gray)Response with default elements, make sure that info.bitsPerPixel() is <= 8. - /// \throw RangeException When info.bitsPerPixel() is negative or greater than 8. - explicit CurveResponse(const ImageInfo& info) : CurveResponse(info.bitsPerPixel()){} - - /// Creates a new (Rgb|Gray)Response with default elements, make sure that bitsPerPixel is <= 8. - /// \throw RangeException When bitsPerPixel is negative or greater than 8. - explicit CurveResponse(Int16 bitsPerPixel){ - if (bitsPerPixel <= 0 || bitsPerPixel > 8){ - throw RangeException(); - } - - UInt16 size = 1 << static_cast(bitsPerPixel); - m_data.reset(new Element8[size]); - for (UInt16 i = 0; i < size; i++){ - m_data[i] = Element8(static_cast(i)); // 0..255 max - } - } - - /// Array of size `2^ImageInfo.bitesPerPixel()`, up to 256 elements (2^8) - Element8* data() noexcept{ - return m_data.get(); - } - - /// Array of size `2^ImageInfo.bitesPerPixel()`, up to 256 elements (2^8) - const Element8* data() const noexcept{ - return m_data.get(); - } - -private: - std::unique_ptr m_data; - -}; - -} - -/// Rgb response class. -class RgbResponse : public Detail::CurveResponse { - -public: - RgbResponse() noexcept{} - - /// Creates a new RgbResponse with default elements, make sure that info.bitesPerPixel() is <= 8. - /// \throw RangeException When info.bitsPerPixel() is negative or greater than 8. - explicit RgbResponse(const ImageInfo& info) : - Detail::CurveResponse(info) {} - - /// Creates a new RgbResponse with default elements, make sure that bitsPerPixel is <= 8. - /// \throw RangeException When bitsPerPixel is negative or greater than 8. - explicit RgbResponse(Int16 bitsPerPixel) : - Detail::CurveResponse(bitsPerPixel) {} - -}; - -/// Gray response class. -class GrayResponse : public Detail::CurveResponse { - -public: - GrayResponse() noexcept{} - - /// Creates a new GrayResponse with default elements, make sure that info.bitesPerPixel() is <= 8. - /// \throw RangeException When info.bitsPerPixel() is negative or greater than 8. - explicit GrayResponse(const ImageInfo& info) : - Detail::CurveResponse(info) {} - - /// Creates a new GrayResponse with default elements, make sure that bitsPerPixel is <= 8. - /// \throw RangeException When bitsPerPixel is negative or greater than 8. - explicit GrayResponse(Int16 bitsPerPixel) : - Detail::CurveResponse(bitsPerPixel) {} - -}; - -} - -#endif // TWPP_DETAIL_FILE_CURVERESPONSE_HPP - diff --git a/twain/twain/twpp/customdata.hpp b/twain/twain/twpp/customdata.hpp deleted file mode 100644 index fb3e004..0000000 --- a/twain/twain/twpp/customdata.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_CUSTOMDATA_HPP -#define TWPP_DETAIL_FILE_CUSTOMDATA_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Structure for sending custom data to source or application. -class CustomData { - -public: - template - using Data = typename Detail::Lock; - - /// Creates empty custom data. - CustomData() noexcept : - m_size(0), m_handle(){} - - /// Creates custom data with allocated memory. - /// \throw std::bad_alloc - explicit CustomData(UInt32 size) : - m_size(size), m_handle(Detail::alloc(size)){} - - /// Locks and returns pointer to custom data memory. - template - Data lock() const noexcept{ - return Data(m_handle.get()); - } - - /// The size of contained memory block. - UInt32 size() const noexcept{ - return m_size; - } - -private: - UInt32 m_size; - Detail::UniqueHandle m_handle; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_CUSTOMDATA_HPP diff --git a/twain/twain/twpp/datasource.hpp b/twain/twain/twpp/datasource.hpp deleted file mode 100644 index 85d82bb..0000000 --- a/twain/twain/twpp/datasource.hpp +++ /dev/null @@ -1,2225 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2018 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_DATASOURCE_HPP -#define TWPP_DETAIL_FILE_DATASOURCE_HPP - -#include "../twpp.hpp" - -namespace Twpp { - - namespace Detail { - - TWPP_DETAIL_PACK_BEGIN - struct AppCapability { - - CapType m_cap; - ConType m_conType; - Handle m_cont; - - }; - TWPP_DETAIL_PACK_END - - struct DoNotFreeHandle { - - DoNotFreeHandle(Handle handle) { - Detail::GlobalMemFuncs::doNotFreeHandle = handle; - } - - ~DoNotFreeHandle() { - Detail::GlobalMemFuncs::doNotFreeHandle = Handle(); - } - - }; - - } - -#define TWPP_ENTRY(SourceClass)\ - extern "C" TWPP_DETAIL_EXPORT Twpp::ReturnCode TWPP_DETAIL_CALLSTYLE \ - DS_Entry(Twpp::Identity* origin, Twpp::DataGroup dg, Twpp::Dat dat, Twpp::Msg msg, void* data){\ - static_assert(\ - std::is_base_of, SourceClass>::value ||\ - std::is_base_of, SourceClass>::value,\ - "Class " #SourceClass " is not derived from SourceFromThis."\ - );\ - return SourceClass::entry(origin, dg, dat, msg, data);\ - } - - /// Result of a data source operation. - /// Contains both return code and status. - class Result { - - public: - /// Creates successful result. - constexpr Result() noexcept : - m_status(), m_rc(ReturnCode::Success) {} - - /// Creates result with supplied return code and status. - constexpr Result(ReturnCode rc, Status status) noexcept : - m_status(status), m_rc(rc) {} - - /// Status part of the result. - constexpr Status status() const noexcept { - return m_status; - } - - /// Return code part of the result. - constexpr ReturnCode returnCode() const noexcept { - return m_rc; - } - - /// Sets status part of the result. - void setStatus(Status status) noexcept { - m_status = status; - } - - /// Sets return code part of the result. - void setReturnCode(ReturnCode rc) noexcept { - m_rc = rc; - } - - constexpr operator ReturnCode() const noexcept { - return m_rc; - } - - constexpr operator Status() const noexcept { - return m_status; - } - - private: - Status m_status; - ReturnCode m_rc; - - }; - - static constexpr inline bool success(const Result& res) noexcept { - return success(res.returnCode()); - } - - - namespace Detail { - - template // false - struct StaticCustomBaseProc { - Result operator()(Dat, Msg, void*) { - return { ReturnCode::Failure, ConditionCode::BadProtocol }; - } - }; - - template - struct StaticCustomBaseProc { - Result operator()(Dat dat, Msg msg, void* data) { - return Derived::staticCustomBase(dat, msg, data); - } - }; - - TWPP_DETAIL_CREATE_HAS_STATIC_METHOD(defaultIdentity) - TWPP_DETAIL_CREATE_HAS_STATIC_METHOD(staticCustomBase) - - } - - namespace SourceFromThisProcs { - - /// Returns data source identity not associated with any instance. - const Identity& defaultIdentity(); - - /// Processes custom TWAIN operations without having any opened connection. - /// DataGroup is always Control. - /// \param dat Type of data. Dat::CustomBase + X. - /// \param msg Message, action to perform. - /// \param data The data, may be null. - /// \return Operation result code. - Result staticCustomBase(Dat dat, Msg msg, void* data); - - } - - /// Base class of a TWAIN data source. - /// It handles instances creation and all static calls. - /// - /// The derived class must: - /// 1) Implement at least all pure virtual methods. - /// 2) Provide `static const Identity& defaultIdentity()`. - /// 3) If hasStaticCustomBaseProc == true, provide - /// `static Result staticCustomBase(Dat dat, Msg msg, void* data)`. - /// - /// After defining your source class, do not forget to use macro - /// TWPP_ENTRY() - /// where the name is a literal, not string: - /// - /// TWPP_ENTRY(Source) // <- no semicolon required - /// \tparam Derived The class inheriting from this. - /// \tparam hasStaticCustomBaseProc {Whether the Derived - /// class handles static custom base operations, see above.} - template - class SourceFromThis { - - public: - SourceFromThis(const SourceFromThis&) = delete; - SourceFromThis& operator=(const SourceFromThis&) = delete; - - SourceFromThis(SourceFromThis&&) = delete; - SourceFromThis& operator=(SourceFromThis&&) = delete; - - virtual ~SourceFromThis() noexcept = default; - - protected: - /// Creates closed instance. - constexpr SourceFromThis() noexcept : - m_lastStatus(ConditionCode::Bummer), m_state(DsState::Closed) {} - - /// The last TWAIN status. - Status lastStatus() const noexcept { - return m_lastStatus; - } - - /// Current TWAIN state. - DsState state() const noexcept { - return m_state; - } - - /// Whether the source is in the supplied TWAIN state. - bool inState(DsState state) const noexcept { - return m_state == state; - } - - /// Whether the source is between min and max states (both inclusive). - bool inState(DsState min, DsState max) const noexcept { - return m_state >= min && m_state <= max; - } - - /// Whether there exists an enabled source. - static bool hasEnabled() noexcept { - for (auto& src : g_sources) { - if (src.inState(DsState::Enabled, DsState::Xferring)) { - return true; - } - } - - return false; - } - - /// Source identity. - const Identity& sourceIdentity() const noexcept { - return m_srcId; - } - - /// Identity of the application that opened the source. - const Identity& applicationIdentity() const noexcept { - return m_appId; - } - - /// Sets current TWAIN state, use with care. - void setState(DsState state) noexcept { - m_state = state; - } - - /// Sets current source identity, use with care. - void setSourceIdentity(const Identity& sourceIdentity) noexcept { - m_srcId = sourceIdentity; - } - - /// Sets current application identity, use with care. - void setApplicationIdentity(const Identity& appIdentity) noexcept { - m_appId = appIdentity; - } - - /// Shortcut for Result(RC::Success, CC::Success). - static constexpr Result success() noexcept { - return { ReturnCode::Success, ConditionCode::Success }; - } - - /// Shortcut for Result(RC::Failure, CC::BadValue). - static constexpr Result badValue() noexcept { - return { ReturnCode::Failure, ConditionCode::BadValue }; - } - - /// Shortcut for Result(RC::Failure, CC::BadProtocol). - static constexpr Result badProtocol() noexcept { - return { ReturnCode::Failure, ConditionCode::BadProtocol }; - } - - /// Shortcut for Result(RC::Failure, CC::SeqError). - static constexpr Result seqError() noexcept { - return { ReturnCode::Failure, ConditionCode::SeqError }; - } - - /// Shortcut for Result(RC::Failure, CC::CapBadOperation). - static constexpr Result capBadOperation() noexcept { - return { ReturnCode::Failure, ConditionCode::CapBadOperation }; - } - - /// Shortcut for Result(RC::Failure, CC::CapUnsupported). - static constexpr Result capUnsupported() noexcept { - return { ReturnCode::Failure, ConditionCode::CapUnsupported }; - } - - /// Shortcut for Result(RC::Failure, CC::Bummber). - static constexpr Result bummer() noexcept { - return { ReturnCode::Failure, ConditionCode::Bummer }; - } - - - /// Notifies application about clicking on OK button. - ReturnCode notifyCloseOk() noexcept { - return notifyApp(Msg::CloseDsOk); - } - - /// Notifies application about clicking on Cancel button. - ReturnCode notifyCloseCancel() noexcept { - return notifyApp(Msg::CloseDsReq); - } - - /// Notifies application about a device event. - ReturnCode notifyDeviceEvent() noexcept { - return notifyApp(Msg::DeviceEvent); - } - - /// Notifies application about ready transfer (after clicking scan button is GUI is shown). - ReturnCode notifyXferReady() noexcept { - return notifyApp(Msg::XferReady); - } - - /// Notifies application scanning complete with no image got - added on 2022-07-02 - ReturnCode notifyEndWithoutImages() noexcept { - return notifyApp(Msg::Null); - } - - - - /// Root of source TWAIN calls. - /// \param origin Identity of the caller. - /// \param dg Data group of the call. - /// \param dat Type of data. - /// \param msg Message, action to perform. - /// \param data The data, may be null. - virtual Result call(const Identity& origin, DataGroup dg, Dat dat, Msg msg, void* data) { - switch (dg) { - case DataGroup::Control: - return control(origin, dat, msg, data); - - case DataGroup::Image: - return image(origin, dat, msg, data); - - case DataGroup::Audio: - return audio(origin, dat, msg, data); - - default: - return badProtocol(); - - } - } - - /// Root of source control TWAIN calls. - /// \param origin Identity of the caller. - /// \param dat Type of data. - /// \param msg Message, action to perform. - /// \param data The data, may be null. - virtual Result control(const Identity& origin, Dat dat, Msg msg, void* data) { - if (!data) { - // all control triplets require data - return badValue(); - } - - switch (dat) { - case Dat::Capability: - return capability(origin, msg, *static_cast(data)); - case Dat::CustomData: - return customData(origin, msg, *static_cast(data)); - case Dat::DeviceEvent: - return deviceEvent(origin, msg, *static_cast(data)); - case Dat::Event: // Windows only - return event(origin, msg, *static_cast(data)); - case Dat::FileSystem: - return fileSystem(origin, msg, *static_cast(data)); - case Dat::Identity: - return identity(origin, msg, *static_cast(data)); - case Dat::PassThrough: - return passThrough(origin, msg, *static_cast(data)); - case Dat::PendingXfers: - return pendingXfers(origin, msg, *static_cast(data)); - case Dat::SetupFileXfer: - return setupFileXfer(origin, msg, *static_cast(data)); - case Dat::SetupMemXfer: - return setupMemXfer(origin, msg, *static_cast(data)); - case Dat::Status: - return status(origin, msg, *static_cast(data)); - case Dat::StatusUtf8: - return statusUtf8(origin, msg, *static_cast(data)); - case Dat::UserInterface: - return userInterface(origin, msg, *static_cast(data)); - case Dat::XferGroup: { - return xferGroup(origin, msg, *static_cast(data)); - } - default: - return badProtocol(); - } - } - - /// Capability TWAIN call. - /// Reset, set and set constraint operations are limited to - /// state DsState::Open (4), override this method if you - /// support CapType::ExtendedCaps. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Capability data. - virtual Result capability(const Identity& origin, Msg msg, Capability& data) { - switch (msg) { - case Msg::Get: - // 4 - 7 - return capabilityGet(origin, data); - - case Msg::GetCurrent: - // 4 - 7 - return capabilityGetCurrent(origin, data); - - case Msg::GetDefault: - // 4 - 7 - return capabilityGetDefault(origin, data); - - case Msg::GetHelp: - if (!inState(DsState::Open)) { - return seqError(); - } - - return capabilityGetHelp(origin, data); - - case Msg::GetLabel: - if (!inState(DsState::Open)) { - return seqError(); - } - - return capabilityGetLabel(origin, data); - - case Msg::GetLabelEnum: - if (!inState(DsState::Open)) { - return seqError(); - } - - return capabilityGetLabelEnum(origin, data); - - case Msg::QuerySupport: - // 4 - 7 - return capabilityQuerySupport(origin, data); - - case Msg::Reset: - // 4, extended: 5, 6, 7 - if (!inState(DsState::Open)) { - return seqError(); - } - - return capabilityReset(origin, data); - - case Msg::ResetAll: - if (!inState(DsState::Open)) { - return seqError(); - } - - return capabilityResetAll(origin); // data has no meaning here - - case Msg::Set: - // 4, extended: 5, 6, 7 - if (!inState(DsState::Open)) { - return seqError(); - } - - if (!data) { - return badValue(); - } - - return capabilitySet(origin, data); - - case Msg::SetConstraint: - // 4, extended: 5, 6, 7 - if (!inState(DsState::Open)) { - return seqError(); - } - - if (!data) { - return badValue(); - } - - return capabilitySetConstraint(origin, data); - - default: - return badProtocol(); - } - } - - /// Get capability TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilityGet(const Identity& origin, Capability& data) = 0; - - /// Get current capability TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilityGetCurrent(const Identity& origin, Capability& data) = 0; - - /// Get default capability TWAIN call. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilityGetDefault(const Identity& origin, Capability& data) = 0; - - /// Get help capability TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilityGetHelp(const Identity& origin, Capability& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Get label capability TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilityGetLabel(const Identity& origin, Capability& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Get label enum capability TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilityGetLabelEnum(const Identity& origin, Capability& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Query support capability TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilityQuerySupport(const Identity& origin, Capability& data) = 0; - - /// Reset capability TWAIN call. - /// Always called in correct state: 4, if you support extended - /// capabilities, override `capability` method. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilityReset(const Identity& origin, Capability& data) = 0; - - /// Reset all capability TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - virtual Result capabilityResetAll(const Identity& origin) = 0; - - /// Set capability TWAIN call. - /// Always called in correct state: 4, if you support extended - /// capabilities, override `capability` method. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilitySet(const Identity& origin, Capability& data) = 0; - - /// Set capability TWAIN call. - /// Always called in correct state: 4, if you support extended - /// capabilities, override `capability` method. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Capability data. - virtual Result capabilitySetConstraint(const Identity& origin, Capability& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - - - /// Custom data TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Custom data. - virtual Result customData(const Identity& origin, Msg msg, CustomData& data) { - if (!inState(DsState::Open)) { - return seqError(); - } - - switch (msg) { - case Msg::Get: - return customDataGet(origin, data); - - case Msg::Set: - return customDataSet(origin, data); - - default: - return badProtocol(); - } - } - - /// Get custom data TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Custom data. - virtual Result customDataGet(const Identity& origin, CustomData& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Set custom data TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Custom data. - virtual Result customDataSet(const Identity& origin, CustomData& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Device event TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Device event data. - virtual Result deviceEvent(const Identity& origin, Msg msg, DeviceEvent& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - return deviceEventGet(origin, data); - } - - /// Get device event TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Device event data. - virtual Result deviceEventGet(const Identity& origin, DeviceEvent& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - - - /// Event TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Event data. - virtual Result event(const Identity& origin, Msg msg, Event& data) { - if (msg != Msg::ProcessEvent) { - return badProtocol(); - } - - if (!inState(DsState::Enabled, DsState::Xferring)) { - return seqError(); - } - return eventProcess(origin, data); - } - -#if defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_MAC) - /// Process event TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Event data. - virtual Result eventProcess(const Identity& origin, Event& data) = 0; -#elif defined(TWPP_DETAIL_OS_LINUX) - /// Process event TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Event data. - virtual Result eventProcess(const Identity& origin, Event& data) { - Detail::unused(origin, data); - return badProtocol(); - } -#else -# error "eventProcess for your platform here" -#endif - - /// Identity TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Identity data. - virtual Result identity(const Identity& origin, Msg msg, Identity& data) { - Result rc; - switch (msg) { - case Msg::Get: - // any state - data = sourceIdentity(); - return success(); - - case Msg::OpenDs: { - if (!inState(DsState::Closed)) { - return seqError(); - } - - setSourceIdentity(data); - setApplicationIdentity(origin); - rc = identityOpenDs(origin); - if (Twpp::success(rc)) { - setState(DsState::Open); - } - - return rc; - } - - case Msg::CloseDs: { - if (inState(DsState::Enabled)) { - setState(DsState::Open); - } - if (!inState(DsState::Open)) { - return seqError(); - } - - rc = identityCloseDs(origin); - if (Twpp::success(rc)) { - setState(DsState::Closed); - } - - return rc; - } - - default: - return badProtocol(); - } - } - - /// Open source identity TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - virtual Result identityOpenDs(const Identity& origin) = 0; - - /// Close source identity TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - virtual Result identityCloseDs(const Identity& origin) = 0; - - /// File system TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data File system data. - virtual Result fileSystem(const Identity& origin, Msg msg, FileSystem& data) { - switch (msg) { - case Msg::AutomaticCaptureDir: - if (!inState(DsState::Open)) { - return seqError(); - } - - return fileSystemAutomatic(origin, data); - - case Msg::ChangeDir: - if (!inState(DsState::Open)) { - return seqError(); - } - - return fileSystemChange(origin, data); - - case Msg::Copy: - if (!inState(DsState::Open)) { - return seqError(); - } - - return fileSystemCopy(origin, data); - - case Msg::CreateDir: - if (!inState(DsState::Open)) { - return seqError(); - } - - return fileSystemCreate(origin, data); - - case Msg::Delete: - if (!inState(DsState::Open)) { - return seqError(); - } - - return fileSystemDelete(origin, data); - - case Msg::FormatMedia: - if (!inState(DsState::Open)) { - return seqError(); - } - - return fileSystemFormat(origin, data); - - case Msg::GetClose: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return fileSystemGetClose(origin, data); - - case Msg::GetFirstFile: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return fileSystemGetFirst(origin, data); - - case Msg::GetInfo: - // 4 - 7 - return fileSystemGetInfo(origin, data); - - case Msg::GetNextFile: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return fileSystemGetNext(origin, data); - - case Msg::Rename: - if (!inState(DsState::Open)) { - return seqError(); - } - - return fileSystemRename(origin, data); - - default: - return badProtocol(); - } - } - - /// Automatic capture directory file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemAutomatic(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Change directory file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemChange(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - - /// Copy file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemCopy(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Create directory file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemCreate(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Delete file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemDelete(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Format media file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemFormat(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Get close file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemGetClose(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Get first file file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemGetFirst(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Get info file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemGetInfo(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Get next file file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemGetNext(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Rename file system TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data File system data. - virtual Result fileSystemRename(const Identity& origin, FileSystem& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - - /// Pass through TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Pass through data. - virtual Result passThrough(const Identity& origin, Msg msg, PassThrough& data) { - if (msg != Msg::PassThrough) { - return badProtocol(); - } - - // 4 - 7 - return passThroughPass(origin, data); - } - - /// Pass through pass through TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Pass through data. - virtual Result passThroughPass(const Identity& origin, PassThrough& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Pending xfers TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Pending xfers data. - virtual Result pendingXfers(const Identity& origin, Msg msg, PendingXfers& data) { - switch (msg) { - case Msg::EndXfer: { - if (!inState(DsState::XferReady, DsState::Xferring)) { - return seqError(); - } - - auto rc = pendingXfersEnd(origin, data); - if (Twpp::success(rc)) { - DataGroup xferGroup = DataGroup::Image; - if (!Twpp::success(this->xferGroup(origin, Msg::Get, xferGroup))) { - xferGroup = DataGroup::Image; - } - - if (xferGroup == DataGroup::Audio) { - setState(DsState::XferReady); - } - else { - //setState(data.count() ? DsState::XferReady : DsState::Enabled); - setState(data.count() ? DsState::XferReady : DsState::Enabled); - } - } - - return rc; - } - - - case Msg::Reset: { - if (!inState(DsState::XferReady)) { - return seqError(); - } - - auto rc = pendingXfersReset(origin, data); - if (Twpp::success(rc)) { - DataGroup xferGroup = DataGroup::Image; - if (!Twpp::success(this->xferGroup(origin, Msg::Get, xferGroup))) { - xferGroup = DataGroup::Image; - } - - if (xferGroup != DataGroup::Audio) { - setState(DsState::Enabled); - } - } - - return rc; - } - - case Msg::StopFeeder: - if (!inState(DsState::XferReady)) { - return seqError(); - } - - return pendingXfersStopFeeder(origin, data); - - case Msg::Get: - if (!inState(DsState::Open, DsState::Xferring)) { - return seqError(); - } - - return pendingXfersGet(origin, data); - - default: - return badProtocol(); - } - } - - /// Get pending xfers TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Pending xfers data. - virtual Result pendingXfersGet(const Identity& origin, PendingXfers& data) = 0; - - /// End xfer pending xfers TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Pending xfers data. - virtual Result pendingXfersEnd(const Identity& origin, PendingXfers& data) = 0; - - /// Reset xfers pending xfers TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Pending xfers data. - virtual Result pendingXfersReset(const Identity& origin, PendingXfers& data) = 0; - - /// Stop feeder pending xfers TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Pending xfers data. - virtual Result pendingXfersStopFeeder(const Identity& origin, PendingXfers& data) = 0; - - /// Setup file xfer TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Setup file xfer data. - virtual Result setupFileXfer(const Identity& origin, Msg msg, SetupFileXfer& data) { - switch (msg) { - case Msg::Get: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return setupFileXferGet(origin, data); - - case Msg::GetDefault: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return setupFileXferGetDefault(origin, data); - - case Msg::Set: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return setupFileXferSet(origin, data); - - case Msg::Reset: - if (!inState(DsState::Open)) { - return seqError(); - } - - return setupFileXferReset(origin, data); - - default: - return badProtocol(); - } - } - - /// Get setup file xfer TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Setup file xfer data. - virtual Result setupFileXferGet(const Identity& origin, SetupFileXfer& data) = 0; - - /// Get default setup file xfer TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Setup file xfer data. - virtual Result setupFileXferGetDefault(const Identity& origin, SetupFileXfer& data) = 0; - - /// Set setup file xfer TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Setup file xfer data. - virtual Result setupFileXferSet(const Identity& origin, SetupFileXfer& data) = 0; - - /// Reset setup file xfer TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Setup file xfer data. - virtual Result setupFileXferReset(const Identity& origin, SetupFileXfer& data) = 0; - - /// Setup memory xfer TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Setup memory xfer data. - virtual Result setupMemXfer(const Identity& origin, Msg msg, SetupMemXfer& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return setupMemXferGet(origin, data); - } - - /// Get setup memory xfer TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Setup memory xfer data. - virtual Result setupMemXferGet(const Identity& origin, SetupMemXfer& data) = 0; - - /// Status TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Status data. - virtual Result status(const Identity& origin, Msg msg, Status& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - return statusGet(origin, data); - } - - /// Get status TWAIN call. - /// Always called in correct state. - /// Default implementation returns last status. - /// \param origin Identity of the caller. - /// \param data Status data. - virtual Result statusGet(const Identity& origin, Status& data) { - Detail::unused(origin); - data = lastStatus(); - return success(); - } - - /// Status utf8 TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Status utf8 data. - virtual Result statusUtf8(const Identity& origin, Msg msg, StatusUtf8& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - // 3 - 7 - return statusUtf8Get(origin, data); - } - - /// Get status utf8 TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Status utf8 data. - virtual Result statusUtf8Get(const Identity& origin, StatusUtf8& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// User interface TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data User interface data. - virtual Result userInterface(const Identity& origin, Msg msg, UserInterface& data) { - Result rc; - switch (msg) { - case Msg::DisableDs: - if (!inState(DsState::Enabled)) { - setState(DsState::Enabled); - } - - rc = userInterfaceDisable(origin, data); - if (Twpp::success(rc)) { - setState(DsState::Open); - } - - return rc; - - case Msg::EnableDs: - if (!inState(DsState::Open) || hasEnabled()) { // only a single source can be enabled at any given time - return seqError(); - } - - rc = userInterfaceEnable(origin, data); - if (Twpp::success(rc) || rc == ReturnCode::CheckStatus) { - if (inState(DsState::Open)) { // allow userInterfaceEnable to transfer to higher states - setState(DsState::Enabled); - //if(!data.showUi()) - // notifyXferReady(); - } - } - - return rc; - - case Msg::EnableDsUiOnly: - if (!inState(DsState::Open)) { - return seqError(); - } - - rc = userInterfaceEnableUiOnly(origin, data); - if (Twpp::success(rc)) { - setState(DsState::Enabled); - } - - return rc; - - default: - return badProtocol(); - } - } - - /// Disable user interface TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data User interface data. - virtual Result userInterfaceDisable(const Identity& origin, UserInterface& data) = 0; - - /// Enable user interface TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data User interface data. - virtual Result userInterfaceEnable(const Identity& origin, UserInterface& data) = 0; - - /// Enable UI only user interface TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data User interface data. - virtual Result userInterfaceEnableUiOnly(const Identity& origin, UserInterface& data) = 0; - - /// Xfer group TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Xfer group data. - virtual Result xferGroup(const Identity& origin, Msg msg, DataGroup& data) { - switch (msg) { - case Msg::Get: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return xferGroupGet(origin, data); - - case Msg::Set: - if (!inState(DsState::XferReady)) { - return seqError(); - } - - return xferGroupSet(origin, data); - - default: - return badProtocol(); - } - } - - /// Get xfer group TWAIN call. - /// Always called in correct state. - /// Default implementation returns DataGroup::Image. - /// \param origin Identity of the caller. - /// \param data Xfer group data. - virtual Result xferGroupGet(const Identity& origin, DataGroup& data) { - Detail::unused(origin); - data = DataGroup::Image; - return success(); - } - - /// Set xfer group TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Xfer group data. - virtual Result xferGroupSet(const Identity& origin, DataGroup& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Root of source image TWAIN calls. - /// - /// Special data to type casts: - /// ExtImageInfo: reinterpret_cast(data) - /// GrayResponse: reinterpret_cast(data) - /// RgbResponse: reinterpret_cast(data) - /// - /// \param origin Identity of the caller. - /// \param dat Type of data. - /// \param msg Message, action to perform. - /// \param data The data, may be null. - virtual Result image(const Identity& origin, Dat dat, Msg msg, void* data) { - if (dat != Dat::ImageFileXfer && !data) { - return badValue(); - } - - switch (dat) { - // TODO CieColor - /*case Dat::CieColor: - return cieColor(origin, msg, *static_cast(data));*/ - case Dat::ExtImageInfo: - return extImageInfo(origin, msg, reinterpret_cast(data)); // ExtImageInfo is simply a `pointer to TW_EXTIMAGEINFO` - case Dat::GrayResponse: - return grayResponse(origin, msg, reinterpret_cast(data)); // GrayResponse is simply a `pointer to TW_GRAYRESPONSE` - case Dat::IccProfile: - return iccProfile(origin, msg, *static_cast(data)); - case Dat::ImageFileXfer: - return imageFileXfer(origin, msg); - case Dat::ImageInfo: - return imageInfo(origin, msg, *static_cast(data)); - case Dat::ImageLayout: - return imageLayout(origin, msg, *static_cast(data)); - case Dat::ImageMemFileXfer: - return imageMemFileXfer(origin, msg, *static_cast(data)); - case Dat::ImageMemXfer: - return imageMemXfer(origin, msg, *static_cast(data)); - case Dat::ImageNativeXfer: - return imageNativeXfer(origin, msg, *static_cast(data)); - case Dat::JpegCompression: - return jpegCompression(origin, msg, *static_cast(data)); - case Dat::Palette8: - return palette8(origin, msg, *static_cast(data)); - case Dat::RgbResponse: - return rgbResponse(origin, msg, reinterpret_cast(data)); // RgbResponse is simply a `pointer to TW_RGBRESPONSE` - default: - return badProtocol(); - } - } - - // TODO CieColor - /* - /// Cie color TWAIN call. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Cie color data. - virtual Result cieColor(const Identity& origin, Msg msg, CieColor& data){ - Detail::unused(origin, msg, data); - return badProtocol(); - }*/ - - /// Ext image info TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Ext image info data. - virtual Result extImageInfo(const Identity& origin, Msg msg, ExtImageInfo& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::Xferring)) { - return seqError(); - } - - return extImageInfoGet(origin, data); - } - - /// Get ext image info TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Ext image info data. - virtual Result extImageInfoGet(const Identity& origin, ExtImageInfo& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Gray response TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Gray response data. - virtual Result grayResponse(const Identity& origin, Msg msg, GrayResponse& data) { - if (!inState(DsState::Open)) { - return seqError(); - } - - switch (msg) { - case Msg::Set: - return grayResponseSet(origin, data); - - case Msg::Reset: - return grayResponseReset(origin, data); - - default: - return badProtocol(); - } - } - - /// Set gray response TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Gray response data. - virtual Result grayResponseSet(const Identity& origin, GrayResponse& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Reset gray response TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Gray response data. - virtual Result grayResponseReset(const Identity& origin, GrayResponse& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// ICC profile TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data ICC profile data. - virtual Result iccProfile(const Identity& origin, Msg msg, IccProfileMemory& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady, DsState::Xferring)) { - return seqError(); - } - - return iccProfileGet(origin, data); - } - - /// Get ICC profile TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data ICC profile data. - virtual Result iccProfileGet(const Identity& origin, IccProfileMemory& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Image file xfer TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - virtual Result imageFileXfer(const Identity& origin, Msg msg) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady)) { - return seqError(); - } - - auto rc = imageFileXferGet(origin); - if (rc == ReturnCode::XferDone) { - setState(DsState::Xferring); - } - - return rc; - } - - /// Get image file xfer TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// Always called in correct state. - /// \param origin Identity of the caller. - virtual Result imageFileXferGet(const Identity& origin) = 0; - - /// Image info TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Image info data. - virtual Result imageInfo(const Identity& origin, Msg msg, ImageInfo& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady, DsState::Xferring)) { - return seqError(); - } - - return imageInfoGet(origin, data); - } - - /// Get image info TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Image info data. - virtual Result imageInfoGet(const Identity& origin, ImageInfo& data) = 0; - - - /// Image layout TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Image layout data. - virtual Result imageLayout(const Identity& origin, Msg msg, ImageLayout& data) { - switch (msg) { - case Msg::Get: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return imageLayoutGet(origin, data); - - case Msg::GetDefault: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return imageLayoutGetDefault(origin, data); - - case Msg::Set: - if (!inState(DsState::Open)) { - return seqError(); - } - - return imageLayoutSet(origin, data); - - case Msg::Reset: - if (!inState(DsState::Open)) { - return seqError(); - } - - return imageLayoutReset(origin, data); - - default: - return badProtocol(); - } - } - - /// Get image layout TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Image layout data. - virtual Result imageLayoutGet(const Identity& origin, ImageLayout& data) = 0; - - /// Get default image layout TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Image layout data. - virtual Result imageLayoutGetDefault(const Identity& origin, ImageLayout& data) = 0; - - /// Set image layout TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Image layout data. - virtual Result imageLayoutSet(const Identity& origin, ImageLayout& data) = 0; - - /// Reset image layout TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Image layout data. - virtual Result imageLayoutReset(const Identity& origin, ImageLayout& data) = 0; - - - /// Image memory file xfer TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Image memory file xfer data. - virtual Result imageMemFileXfer(const Identity& origin, Msg msg, ImageMemFileXfer& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady)) { - return seqError(); - } - - auto rc = imageMemFileXferGet(origin, data); - if (rc == ReturnCode::XferDone) { - setState(DsState::Xferring); - } - - return rc; - } - - /// Get image memory file xfer TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Image memory file xfer data. - virtual Result imageMemFileXferGet(const Identity& origin, ImageMemFileXfer& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Image memory xfer TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Image memory xfer data. - virtual Result imageMemXfer(const Identity& origin, Msg msg, ImageMemXfer& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady, DsState::Xferring)) { - return seqError(); - } - - auto rc = imageMemXferGet(origin, data); - if (Twpp::success(rc) || rc == ReturnCode::XferDone) { - setState(DsState::Xferring); - } - - return rc; - } - - /// Get image memory xfer TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Image memory xfer data. - virtual Result imageMemXferGet(const Identity& origin, ImageMemXfer& data) = 0; - - /// Image native xfer TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Handle to image native xfer data. - virtual Result imageNativeXfer(const Identity& origin, Msg msg, ImageNativeXfer& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady)) { - return seqError(); - } - - auto rc = imageNativeXferGet(origin, data); - if (rc == ReturnCode::XferDone) { - setState(DsState::Xferring); - } - - return rc; - } - - /// Get image native xfer TWAIN call. - /// Always called in correct state. - /// \param origin Identity of the caller. - /// \param data Handle to image native xfer data. - virtual Result imageNativeXferGet(const Identity& origin, ImageNativeXfer& data) = 0; - - /// JPEG compression TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data JPEG compression data. - virtual Result jpegCompression(const Identity& origin, Msg msg, JpegCompression& data) { - switch (msg) { - case Msg::Get: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return jpegCompressionGet(origin, data); - - case Msg::GetDefault: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return jpegCompressionGetDefault(origin, data); - - case Msg::Set: - if (!inState(DsState::Open)) { - return seqError(); - } - - return jpegCompressionSet(origin, data); - - case Msg::Reset: - if (!inState(DsState::Open)) { - return seqError(); - } - - return jpegCompressionReset(origin, data); - - default: - return badProtocol(); - } - } - - /// Get JPEG compression TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data JPEG compression data. - virtual Result jpegCompressionGet(const Identity& origin, JpegCompression& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Get default JPEG compression TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data JPEG compression data. - virtual Result jpegCompressionGetDefault(const Identity& origin, JpegCompression& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Set JPEG compression TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data JPEG compression data. - virtual Result jpegCompressionSet(const Identity& origin, JpegCompression& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Reset JPEG compression TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data JPEG compression data. - virtual Result jpegCompressionReset(const Identity& origin, JpegCompression& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Palette8 TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Palette8 data. - virtual Result palette8(const Identity& origin, Msg msg, Palette8& data) { - switch (msg) { - case Msg::Get: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return palette8Get(origin, data); - - case Msg::GetDefault: - if (!inState(DsState::Open, DsState::XferReady)) { - return seqError(); - } - - return palette8GetDefault(origin, data); - - case Msg::Set: - if (!inState(DsState::Open)) { - return seqError(); - } - - return palette8Set(origin, data); - - case Msg::Reset: - if (!inState(DsState::Open)) { - return seqError(); - } - - return palette8Reset(origin, data); - - default: - return badProtocol(); - } - } - - /// Get Palette8 TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Palette8 data. - virtual Result palette8Get(const Identity& origin, Palette8& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Get default Palette8 TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Palette8 data. - virtual Result palette8GetDefault(const Identity& origin, Palette8& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Set Palette8 TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Palette8 data. - virtual Result palette8Set(const Identity& origin, Palette8& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Reset Palette8 TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Palette8 data. - virtual Result palette8Reset(const Identity& origin, Palette8& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// RGB response TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data RGB response data. - virtual Result rgbResponse(const Identity& origin, Msg msg, RgbResponse& data) { - if (!inState(DsState::Open)) { - return seqError(); - } - - switch (msg) { - case Msg::Set: - return rgbResponseSet(origin, data); - - case Msg::Reset: - return rgbResponseReset(origin, data); - - default: - return badProtocol(); - } - } - - /// Set RGB response TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data RGB response data. - virtual Result rgbResponseSet(const Identity& origin, RgbResponse& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Reset RGB response TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data RGB response data. - virtual Result rgbResponseReset(const Identity& origin, RgbResponse& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - - /// Root of source audio TWAIN calls. - /// \param origin Identity of the caller. - /// \param dat Type of data. - /// \param msg Message, action to perform. - /// \param data The data, may be null. - virtual Result audio(const Identity& origin, Dat dat, Msg msg, void* data) { - if (dat != Dat::AudioFileXfer && !data) { - return badValue(); - } - - switch (dat) { - case Dat::AudioFileXfer: - return audioFileXfer(origin, msg); - case Dat::AudioInfo: - return audioInfo(origin, msg, *static_cast(data)); - case Dat::AudioNativeXfer: - return audioNativeXfer(origin, msg, *static_cast(data)); - default: - return badProtocol(); - } - } - - /// Audio file xfer TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - virtual Result audioFileXfer(const Identity& origin, Msg msg) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady)) { - return seqError(); - } - - auto rc = audioFileXferGet(origin); - if (rc == ReturnCode::XferDone) { - setState(DsState::Xferring); - } - - return rc; - } - - /// Get audio file xfer TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - virtual Result audioFileXferGet(const Identity& origin) { - Detail::unused(origin); - return badProtocol(); - } - - /// Audio info TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Audio info data. - virtual Result audioInfo(const Identity& origin, Msg msg, AudioInfo& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady, DsState::Xferring)) { - return seqError(); - } - - return audioInfoGet(origin, data); - } - - /// Get audio info TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Audio info data. - virtual Result audioInfoGet(const Identity& origin, AudioInfo& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - /// Audio native xfer TWAIN call. - /// \param origin Identity of the caller. - /// \param msg Message, action to perform. - /// \param data Handle to audio native xfer data. - virtual Result audioNativeXfer(const Identity& origin, Msg msg, AudioNativeXfer& data) { - if (msg != Msg::Get) { - return badProtocol(); - } - - if (!inState(DsState::XferReady)) { - return seqError(); - } - - auto rc = audioNativeXferGet(origin, data); - if (Twpp::success(rc)) { - setState(DsState::Xferring); - } - - return rc; - } - - /// Get audio native xfer TWAIN call. - /// Always called in correct state. - /// Default implementation does nothing. - /// \param origin Identity of the caller. - /// \param data Handle to audio native xfer data. - virtual Result audioNativeXferGet(const Identity& origin, AudioNativeXfer& data) { - Detail::unused(origin, data); - return badProtocol(); - } - - private: - ReturnCode notifyApp(Msg msg) noexcept { - switch (msg) { - case Msg::XferReady: - if (!inState(DsState::Enabled)) { - return ReturnCode::Failure; - } - - break; - case Msg::CloseDsOk: - case Msg::CloseDsReq: - if (!inState(DsState::Enabled, DsState::Xferring)) { - return ReturnCode::Failure; - } - - break; - default: - break; - } - - auto rc = g_entry(&m_srcId, &m_appId, DataGroup::Control, Dat::Null, msg, nullptr); - if (Twpp::success(rc)) { - switch (msg) { - case Msg::XferReady: - setState(DsState::XferReady); - break; - case Msg::CloseDsOk: - case Msg::CloseDsReq: - setState(DsState::Enabled); - break; - default: - break; - } - } - - return rc; - } - - Result callRoot(Identity* origin, DataGroup dg, Dat dat, Msg msg, void* data) noexcept { - if (!origin) { - return badProtocol(); - } - - bool isCapability = dg == DataGroup::Control && dat == Dat::Capability && data != nullptr; - try { - return isCapability - ? callCapability(*origin, dg, dat, msg, data) - : call(*origin, dg, dat, msg, data); - } - catch (const std::bad_alloc&) { - return { ReturnCode::Failure, ConditionCode::LowMemory }; - } - catch (...) { - // the exception would be caught in the static handler below - // that would set static status, we want to set local one - return bummer(); - } - } - - Result callCapability(const Identity& origin, DataGroup dg, Dat dat, Msg msg, void* data) { - // it is the responsibility of the APP to free capability handle - // we must assume the APP does not set the handle to zero after freeing it - // that would break capability (handle) move-assignment operator - // make sure such handle is not freed - Detail::AppCapability& cap = *static_cast(data); - Detail::DoNotFreeHandle doNotFree(cap.m_cont); - Detail::unused(doNotFree); - - return call(origin, dg, dat, msg, data); - } - - - Identity m_srcId; - Identity m_appId; - Status m_lastStatus; - DsState m_state; - - - static typename std::list::iterator find(Identity* origin) noexcept { - if (origin) { - for (auto it = g_sources.begin(); it != g_sources.end(); ++it) { - if (it->m_appId.id() == origin->id()) { - return it; - } - } - } - - return g_sources.end(); - } - - static void resetDsm() { - g_entry = nullptr; - -#if defined(TWPP_DETAIL_OS_WIN32) - g_dsm.unload(); -#endif - } - - static Result staticCall(typename std::list::iterator src, Identity* origin, - DataGroup dg, Dat dat, Msg msg, void* data) { - -#if defined(TWPP_DETAIL_OS_WIN32) - if (!g_entry) { - if (!g_dsm && !g_dsm.load(true)) { - return bummer(); - } - - g_entry = g_dsm.resolve(); - } -#endif - - if (!g_entry) { - return bummer(); - } - - auto rc = src->callRoot(origin, dg, dat, msg, data); - src->m_lastStatus = rc.status(); - - if (dg == DataGroup::Control && dat == Dat::Identity && ( - (msg == Msg::CloseDs && Twpp::success(rc)) || - (msg == Msg::OpenDs && !Twpp::success(rc)) - ) - ) { - g_sources.erase(src); - if (g_sources.empty()) { - resetDsm(); - } - } - - return rc; - } - - static Result staticControl(Identity* origin, DataGroup dg, Dat dat, Msg msg, void* data) { - if (dg != DataGroup::Control) { - return seqError(); - } - - switch (dat) { - case Dat::EntryPoint: - if (msg == Msg::Set) { - if (!data) { - return badValue(); - } - - auto& e = *static_cast(data); - g_entry = e.m_entry; - Detail::setMemFuncs(e.m_alloc, e.m_free, e.m_lock, e.m_unlock); - return success(); - } - - break; - - case Dat::Status: { - if (msg == Msg::Get) { - if (!data) { - return badValue(); - } - - *static_cast(data) = g_lastStatus; - return success(); - } - - break; - } - - case Dat::Identity: { - switch (msg) { - case Msg::Get: { - if (!data) { - return badValue(); - } - - static_assert(Detail::HasStaticMethod_defaultIdentity::value, - "Your source class lacks `static const Identity& defaultIdentity()` method."); - - auto& ident = *static_cast(data); - const Identity& def = Derived::defaultIdentity(); - ident = Identity(ident.id(), def.version(), def.protocolMajor(), - def.protocolMinor(), def.dataGroupsRaw(), def.manufacturer(), - def.productFamily(), def.productName()); - - return success(); - } - - case Msg::OpenDs: { - g_sources.emplace_back(); - return staticCall(--g_sources.end(), origin, dg, dat, msg, data); - } - - case Msg::CloseDs: - // not open yet - return success(); - - case Msg::UserSelect: - if (!data) { - return badValue(); - } - else - { - auto& ident = *static_cast(data); - - return Derived::selectIdentity(ident); - - return success(); - } - break; - - default: - break; - } - - break; - } - - default: - if (dat >= Dat::CustomBase) { - static_assert(Detail::HasStaticMethod_staticCustomBase::value || - !hasStaticCustomBaseProc, - "Your source class lacks `static Result staticCustomBase(Dat, Msg, void*)` method."); - - return Detail::StaticCustomBaseProc()(dat, msg, data); - } - - break; - } - - return badProtocol(); - } - - public: - /// TWAIN entry, do not call from data source. - static ReturnCode entry(Identity* origin, DataGroup dg, Dat dat, Msg msg, void* data) noexcept { - auto src = find(origin); - //FileTools::write_log("D:\\1.txt", "call:datagroup-" + to_string((int)dg) + "dat-" + to_string(int(dat)) + "msg-" + to_string(int(msg))); - try { - auto rc = src == g_sources.end() ? - staticControl(origin, dg, dat, msg, data) : - staticCall(src, origin, dg, dat, msg, data); - - g_lastStatus = rc.status(); - return rc.returnCode(); - } - catch (const std::bad_alloc&) { - g_lastStatus = ConditionCode::LowMemory; - return ReturnCode::Failure; - } - catch (...) { - // we can't throw exceptions out of data sources - // the C interface can't really handle them - // especially when there are different implementations - g_lastStatus = ConditionCode::Bummer; - return ReturnCode::Failure; - } - } - - private: - static std::list g_sources; - static Detail::DsmEntry g_entry; - static Status g_lastStatus; - -#if defined(TWPP_DETAIL_OS_WIN32) - static Detail::DsmLib g_dsm; // only old windows dsm requires this -#endif - - }; - - template - std::list SourceFromThis::g_sources; - - template - Detail::DsmEntry SourceFromThis::g_entry; - - template - Status SourceFromThis::g_lastStatus = ConditionCode::Bummer; - -#if defined(TWPP_DETAIL_OS_WIN32) - template - Detail::DsmLib SourceFromThis::g_dsm; -#endif - -} - -#endif // TWPP_DETAIL_FILE_DATASOURCE_HPP - diff --git a/twain/twain/twpp/deviceevent.hpp b/twain/twain/twpp/deviceevent.hpp deleted file mode 100644 index cdf530a..0000000 --- a/twain/twain/twpp/deviceevent.hpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_DEVICEEVENT_HPP -#define TWPP_DETAIL_FILE_DEVICEEVENT_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Information about event sent by source. -class DeviceEvent { - -public: - /// Event type. - enum class Type : UInt16 { // Capability->UInt16, DeviceEvent->UInt32 - CheckAutomaticCapture = 0, - CheckBattery = 1, - CheckDeviceOnline = 2, - CheckFlash = 3, - CheckPowerSupply = 4, - CheckResolution = 5, - DeviceAdded = 6, - DeviceOffline = 7, - DeviceReady = 8, - DeviceRemoved = 9, - ImageCaptured = 10, - ImageDeleted = 11, - PaperDoubleFeed = 12, - PaperJam = 13, - LampFailure = 14, - PowerSave = 15, - PowerSaveNotify = 16, - CustomEvents = 0x8000 - }; - - /// Creates event with only type and device name set. - static constexpr DeviceEvent simple(Type type, const Str255& deviceName) noexcept; - - /// Creates event for checking battery. - static constexpr DeviceEvent checkBattery( - const Str255& deviceName, - UInt32 batteryMinutes, - Int16 batteryPercentage - ) noexcept; - - /// Creates event for checking power supply. - static constexpr DeviceEvent checkPowerSupply( - const Str255& deviceName, - PowerSupply powerSupply - ) noexcept; - - /// Creates event for checking resolution. - static constexpr DeviceEvent checkResolution( - const Str255& deviceName, - Fix32 xres, - Fix32 yres - ) noexcept; - - /// Creates event for checking flash settings. - static constexpr DeviceEvent checkFlash( - const Str255& deviceName, - Flash flash - ) noexcept; - - /// Creates event for checking number of images camera is going to capture. - static constexpr DeviceEvent checkAutomaticCapture( - const Str255& deviceName, - UInt32 autoCapture, - UInt32 timeBeforeFirstCapture, - UInt32 timeBetweenCaptures - ) noexcept; - - /// Creates uninitialized deice event. - constexpr DeviceEvent() noexcept : - m_type(static_cast(Type::CheckAutomaticCapture)), m_batteryMinutes(0), - m_batteryPercent(0), m_powerSupply(static_cast(PowerSupply::External)), - m_flashUsed(static_cast(Flash::None)), m_autoCapture(0), - m_timeBeforeFirstCapture(0), m_timeBetweenCaptures(0){} - - /// Event type. - constexpr Type type() const noexcept{ - return static_cast(m_type); - } - - /// Name of the device that sent the event. - constexpr const Str255& deviceName() const noexcept{ - return m_deviceName; - } - - /// Minutes of battery power remaining. - /// Valid only for Type::CheckBattery. - constexpr UInt32 batteryMinutes() const noexcept{ - return m_batteryMinutes; - } - - /// Percentage of battery power remaining. - /// Valid only for Type::CheckBattery. - constexpr Int16 batteryPercentage() const noexcept{ - return m_batteryPercent; - } - - /// Power supply in use. - /// Valid only for Type::CheckPowerSupply. - constexpr PowerSupply powerSupply() const noexcept{ - return static_cast(m_powerSupply); - } - - /// X resolution. - /// Valif only for Type::CheckResolution. - constexpr Fix32 xResolution() const noexcept{ - return m_xres; - } - - /// Y resolution. - /// Valid only for Type::CheckResolution. - constexpr Fix32 yResolution() const noexcept{ - return m_yres; - } - - /// Flash settings. - /// Valid only for Type::CheckFlash. - constexpr Flash flash() const noexcept{ - return static_cast(m_flashUsed); - } - - /// Number of images camera will capture. - /// Valid only for Type::CheckAutomaticCapture. - constexpr UInt32 automaticCapture() const noexcept{ - return m_autoCapture; - } - - /// Number of seconds before first capture. - /// Valid only for Type::CheckAutomaticCapture. - constexpr UInt32 timeBeforeFirstCapture() const noexcept{ - return m_timeBeforeFirstCapture; - } - - /// Number of 1/100-seconds between captures. - /// Valid only for Type::CheckAutomaticCapture. - constexpr UInt32 timeBetweenCaptures() const noexcept{ - return m_timeBetweenCaptures; - } - -private: - constexpr DeviceEvent( - Type type, - const Str255& deviceName, - UInt32 batteryMinutes, - Int16 batteryPercentage, - PowerSupply powerSupply, - Fix32 xres, - Fix32 yres, - Flash flash, - UInt32 autoCapture, - UInt32 tbfc, - UInt32 tbc - ) noexcept : - m_type(static_cast(type)), m_deviceName(deviceName), - m_batteryMinutes(batteryMinutes), m_batteryPercent(batteryPercentage), - m_powerSupply(static_cast(powerSupply)), m_xres(xres), m_yres(yres), - m_flashUsed(static_cast(flash)), m_autoCapture(autoCapture), - m_timeBeforeFirstCapture(tbfc), m_timeBetweenCaptures(tbc){} - - UInt32 m_type; - Str255 m_deviceName; - UInt32 m_batteryMinutes; - Int16 m_batteryPercent; - Int32 m_powerSupply; - Fix32 m_xres; - Fix32 m_yres; - UInt32 m_flashUsed; - UInt32 m_autoCapture; - UInt32 m_timeBeforeFirstCapture; - UInt32 m_timeBetweenCaptures; - -}; -TWPP_DETAIL_PACK_END - -// must be defined outside the class because of msvc2015 -constexpr inline DeviceEvent DeviceEvent::simple(Type type, const Str255& deviceName) noexcept{ - return DeviceEvent(type, deviceName, 0, 0, PowerSupply::External, Fix32(), Fix32(), Flash::None, 0, 0, 0); -} - -constexpr inline DeviceEvent DeviceEvent::checkBattery( - const Str255& deviceName, - UInt32 batteryMinutes, - Int16 batteryPercentage -) noexcept{ - return DeviceEvent(Type::CheckBattery, deviceName, batteryMinutes, batteryPercentage, PowerSupply::External, Fix32(), Fix32(), Flash::None, 0, 0, 0); -} - -constexpr inline DeviceEvent DeviceEvent::checkPowerSupply( - const Str255& deviceName, - PowerSupply powerSupply -) noexcept{ - return DeviceEvent(Type::CheckPowerSupply, deviceName, 0, 0, powerSupply, Fix32(), Fix32(), Flash::None, 0, 0, 0); -} - -constexpr inline DeviceEvent DeviceEvent::checkResolution( - const Str255& deviceName, - Fix32 xres, - Fix32 yres -) noexcept{ - return DeviceEvent(Type::CheckResolution, deviceName, 0, 0, PowerSupply::External, xres, yres, Flash::None, 0, 0, 0); -} - -constexpr inline DeviceEvent DeviceEvent::checkFlash( - const Str255& deviceName, - Flash flash -) noexcept{ - return DeviceEvent(Type::CheckFlash, deviceName, 0, 0, PowerSupply::External, Fix32(), Fix32(), flash, 0, 0, 0); -} - -constexpr inline DeviceEvent DeviceEvent::checkAutomaticCapture( - const Str255& deviceName, - UInt32 autoCapture, - UInt32 timeBeforeFirstCapture, - UInt32 timeBetweenCaptures -) noexcept{ - return DeviceEvent(Type::CheckAutomaticCapture, deviceName, 0, 0, PowerSupply::External, - Fix32(), Fix32(), Flash::None, autoCapture, timeBeforeFirstCapture, timeBetweenCaptures); -} - -} - -#endif // TWPP_DETAIL_FILE_DEVICEEVENT_HPP diff --git a/twain/twain/twpp/element8.hpp b/twain/twain/twpp/element8.hpp deleted file mode 100644 index 585d571..0000000 --- a/twain/twain/twpp/element8.hpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_ELEMENT8_HPP -#define TWPP_DETAIL_FILE_ELEMENT8_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Element in a palette consisting of 3 parts (RGB, CMY, ...) -/// in the order of the type alphabetic representation. -class Element8 { - -public: - /// Creates zero-initialized element. - constexpr Element8() noexcept : - m_index(0), m_channel1(0), m_channel2(0), m_channel3(0){} - - /// Creates zero-initialized element with specified index. - explicit constexpr Element8(UInt8 index) noexcept : - m_index(index), m_channel1(0), m_channel2(0), m_channel3(0){} - - /// Creates element with set channels. - constexpr Element8( - UInt8 channel1, - UInt8 channel2, - UInt8 channel3 - ) noexcept : - m_index(0), m_channel1(channel1), m_channel2(channel2), - m_channel3(channel3){} - - /// Creates element with set channels at index. - constexpr Element8( - UInt8 index, - UInt8 channel1, - UInt8 channel2, - UInt8 channel3 - ) noexcept : - m_index(index), m_channel1(channel1), m_channel2(channel2), - m_channel3(channel3){} - - /// Index of the element in palette. - constexpr UInt8 index() const noexcept{ - return m_index; - } - - /// Sets index of the element in palette. - void setIndex(UInt8 index) noexcept{ - m_index = index; - } - - /// Channel 1 information. - constexpr UInt8 channel1() const noexcept{ - return m_channel1; - } - - /// Sets channel 1 information. - void setChannel1(UInt8 channel1) noexcept{ - m_channel1 = channel1; - } - - /// Channel 2 information. - constexpr UInt8 channel2() const noexcept{ - return m_channel2; - } - - /// Sets channel 2 information. - void setChannel2(UInt8 channel2) noexcept{ - m_channel2 = channel2; - } - - /// Channel 3 information. - constexpr UInt8 channel3() const noexcept{ - return m_channel3; - } - - /// Sets channel 3 information. - void setChannel3(UInt8 channel3) noexcept{ - m_channel3 = channel3; - } - -private: - UInt8 m_index; - UInt8 m_channel1; - UInt8 m_channel2; - UInt8 m_channel3; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_ELEMENT8_HPP diff --git a/twain/twain/twpp/enums.hpp b/twain/twain/twpp/enums.hpp deleted file mode 100644 index 9a51b96..0000000 --- a/twain/twain/twpp/enums.hpp +++ /dev/null @@ -1,1459 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_ENUMS_HPP -#define TWPP_DETAIL_FILE_ENUMS_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -enum class Alarm : UInt16 { - General = 0, // aka TWAL_ALARM - FeederError = 1, - FeederWarning = 2, - BarCode = 3, - DoubleFeed = 4, - Jam = 5, - PatchCode = 6, - Power = 7, - Skew = 8 -}; - -/// Argument types. -enum class Dat : UInt16 { - Null = 0x0000, - Capability = 0x0001, - Event = 0x0002, - Identity = 0x0003, - Parent = 0x0004, - PendingXfers = 0x0005, - SetupMemXfer = 0x0006, - SetupFileXfer = 0x0007, - Status = 0x0008, - UserInterface = 0x0009, - XferGroup = 0x000a, - CustomData = 0x000c, - DeviceEvent = 0x000d, - FileSystem = 0x000e, - PassThrough = 0x000f, - Callback = 0x0010, - StatusUtf8 = 0x0011, - Callback2 = 0x0012, - ImageInfo = 0x0101, - ImageLayout = 0x0102, - ImageMemXfer = 0x0103, - ImageNativeXfer = 0x0104, - ImageFileXfer = 0x0105, - CieColor = 0x0106, - GrayResponse = 0x0107, - RgbResponse = 0x0108, - JpegCompression = 0x0109, - Palette8 = 0x010a, - ExtImageInfo = 0x010b, - Filter = 0x010c, - AudioFileXfer = 0x0201, - AudioInfo = 0x0202, - AudioNativeXfer = 0x0203, - IccProfile = 0x0401, - ImageMemFileXfer = 0x0402, - EntryPoint = 0x0403, - - CustomBase = 0x8000 -}; - -/// Values of CapType::IAutoSize. -enum class AutoSize : UInt16 { - None = 0, - Auto = 1, - Current = 2 -}; - -/// Values of CapType::ISupportedBarcodeTypes. -enum class BarCodeType : UInt16 { - ThreeOfNine = 0, - ThreeOfFiveInterleaved = 1, - ThreeOfFiveNonInterleaved = 2, - Code93 = 3, - Code128 = 4, - Ucc128 = 5, - CodaBar = 6, - Upca = 7, - Upce = 8, - Ean8 = 9, - Ean13 = 10, - Postnet = 11, - Pdf417 = 12, - TwoOfFiveIndustrial = 13, - TwoOfFiveMatrix = 14, - TwoOfFiveDatalogic = 15, - TwoOfFiveIata = 16, - ThreeOfNineFullAscii = 17, - CodaBarWithStartStop = 18, - MaxiCode = 19, - QrCode = 20 -}; - -/// Values of CapType::IBitDepthReduction. -enum class BitDepthReduction : UInt16 { - Threshold = 0, - HalfTone = 1, - CustHalfTone = 2, - Diffusion = 3, - DynamicThreshold = 4 -}; - -/// Values of CapType::IBitOrder. -enum class BitOrder : UInt16 { - LsbFirst = 0, - MsbFirst = 1 -}; - -/// Values of CapType::CameraSide. -enum class CameraSide : UInt16 { - Both = 0, - Top = 1, - Bottom = 2 -}; - -enum class ConditionCode : UInt16 { - Success = 0, - Bummer = 1, - LowMemory = 2, - NoDs = 3, - MaxConnections = 4, - OperationError = 5, - BadCap = 6, - BadProtocol = 9, - BadValue = 10, - SeqError = 11, - BadDest = 12, - CapUnsupported = 13, - CapBadOperation = 14, - CapSeqError = 15, - Denied = 16, - FileExists = 17, - FileNotFound = 18, - NotEmpty = 19, - PaperJam = 20, - PaperDoubleFeed = 21, - FileWriteError = 22, - CheckDeviceOnline = 23, - InterLock = 24, - DamagedCorner = 25, - FocusError = 26, - DocTooLight = 27, - DocTooDark = 28, - NoMedia = 29, - - CustomBase = 0x8000 -}; - -typedef ConditionCode CC; - -static inline constexpr bool success(CC cc) noexcept{ - return cc == CC::Success; -} - -/// Capability container type. -enum class ConType : UInt16 { - Array = 3, - Enumeration = 4, - OneValue = 5, - Range = 6, - DontCare = 0xFFFF -}; - -/// Capability type. -enum class CapType : UInt16 { - XferCount = 0x0001, - ICompression = 0x0100, - IPixelType = 0x0101, - IUnits = 0x0102, - IXferMech = 0x0103, - Author = 0x1000, - Caption = 0x1001, - FeederEnabled = 0x1002, - FeederLoaded = 0x1003, - TimeDate = 0x1004, - SupportedCaps = 0x1005, - ExtendedCaps = 0x1006, - AutoFeed = 0x1007, - ClearPage = 0x1008, - FeedPage = 0x1009, - RewindPage = 0x100a, - Indicators = 0x100b, - PaperDetectable = 0x100d, - UiControllable = 0x100e, - DeviceOnline = 0x100f, - AutoScan = 0x1010, - ThumbnailsEnabled = 0x1011, - Duplex = 0x1012, - DuplexEnabled = 0x1013, - EnableDsUiOnly = 0x1014, - CustomDsData = 0x1015, - Endorser = 0x1016, - JobControl = 0x1017, - Alarms = 0x1018, - AlarmVolume = 0x1019, - AutomaticCapture = 0x101a, - TimeBeforeFirstCapture = 0x101b, - TimeBetweenCaptures = 0x101c, - ClearBuffers = 0x101d, - MaxBatchBuffers = 0x101e, - DeviceTimeDate = 0x101f, - PowerSupply = 0x1020, - CameraPreviewUi = 0x1021, - DeviceEvent = 0x1022, - SerialNumber = 0x1024, - Printer = 0x1026, - PrinterEnabled = 0x1027, - PrinterIndex = 0x1028, - PrinterMode = 0x1029, - PrinterString = 0x102a, - PrinterSuffix = 0x102b, - Language = 0x102c, - FeederAlignment = 0x102d, - FeederOrder = 0x102e, - ReacquireAllowed = 0x1030, - BatteryMinutes = 0x1032, - BatteryPercentage = 0x1033, - CameraSide = 0x1034, - Segmented = 0x1035, - CameraEnabled = 0x1036, - CameraOrder = 0x1037, - MicrEnabled = 0x1038, - FeederPrep = 0x1039, - FeederPocket = 0x103a, - AutomaticSenseMedium = 0x103b, - CustomInterfaceGuid = 0x103c, - SupportedCapsSegmentUnique = 0x103d, - SupportedDats = 0x103e, - DoubleFeedDetection = 0x103f, - DoubleFeedDetectionLength = 0x1040, - DoubleFeedDetectionSensitivity = 0x1041, - DoubleFeedDetectionResponse = 0x1042, - PaperHandling = 0x1043, - IndicatorsMode = 0x1044, - PrinterVerticalOffset = 0x1045, - PowerSaveTime = 0x1046, - PrinterCharRotation = 0x1047, - PrinterFontStyle = 0x1048, - PrinterIndexLeadChar = 0x1049, - PrinterIndexMaxValue = 0x104A, - PrinterIndexNumDigits = 0x104B, - PrinterIndexStep = 0x104C, - PrinterIndexTrigger = 0x104D, - PrinterStringPreview = 0x104E, - IAutoBright = 0x1100, - IBrightness = 0x1101, - IContrast = 0x1103, - ICustHalfTone = 0x1104, - IExposureTime = 0x1105, - IFilter = 0x1106, - IFlashUsed = 0x1107, - IGamma = 0x1108, - IHalfTones = 0x1109, - IHighLight = 0x110a, - IImageFileFormat = 0x110c, - ILampState = 0x110d, - ILightSource = 0x110e, - IOrientation = 0x1110, - IPhysicalWidth = 0x1111, - IPhysicalHeight = 0x1112, - IShadow = 0x1113, - IFrames = 0x1114, - IXNativeResolution = 0x1116, - IYNativeResolution = 0x1117, - IXResolution = 0x1118, - IYResolution = 0x1119, - IMaxFrames = 0x111a, - ITiles = 0x111b, - IBitOrder = 0x111c, - ICcittKFactor = 0x111d, - ILightPath = 0x111e, - IPixelFlavor = 0x111f, - IPlanarChunky = 0x1120, - IRotation = 0x1121, - ISupportedSizes = 0x1122, - IThreshold = 0x1123, - IXScaling = 0x1124, - IYScaling = 0x1125, - IBitOrderCodes = 0x1126, - IPixelFlavorCodes = 0x1127, - IJpegPixelType = 0x1128, - ITimeFill = 0x112a, - IBitDepth = 0x112b, - IBitDepthReduction = 0x112c, - IUndefinedImageSize = 0x112d, - IImageDataSet = 0x112e, - IExtImageInfo = 0x112f, - IMinimumHeight = 0x1130, - IMinimumWidth = 0x1131, - IAutoDiscardBlankPages = 0x1134, - IFlipRotation = 0x1136, - IBarCodeDetectionEnabled = 0x1137, - ISupportedBarCodeTypes = 0x1138, - IBarCodeMaxSearchPriorities = 0x1139, - IBarCodeSearchPriorities = 0x113a, - IBarCodeSearchMode = 0x113b, - IBarCodeMaxRetries = 0x113c, - IBarCodeTimeOut = 0x113d, - IZoomFactor = 0x113e, - IPatchCodeDetectionEnabled = 0x113f, - ISupportedPatchCodeTypes = 0x1140, - IPatchCodeMaxSearchPriorities = 0x1141, - IPatchCodeSearchPriorities = 0x1142, - IPatchCodeSearchMode = 0x1143, - IPatchCodeMaxRetries = 0x1144, - IPatchCodeTimeOut = 0x1145, - IFlashUsed2 = 0x1146, - IImageFilter = 0x1147, - INoiseFilter = 0x1148, - IOverScan = 0x1149, - IAutomaticBorderDetection = 0x1150, - IAutomaticDeskew = 0x1151, - IAutomaticRotate = 0x1152, - IJpegQuality = 0x1153, - IFeederType = 0x1154, - IIccProfile = 0x1155, - IAutoSize = 0x1156, - IAutomaticCropUsesFrame = 0x1157, - IAutomaticLengthDetection = 0x1158, - IAutomaticColorEnabled = 0x1159, - IAutomaticColorNonColorPixelType = 0x115a, - IColorManagementEnabled = 0x115b, - IImageMerge = 0x115c, - IImageMergeHeightThreshold = 0x115d, - ISupportedExtImageInfo = 0x115e, - IFilmType = 0x115f, - IMirror = 0x1160, - IJpegSubSampling = 0x1161, - AXferMech = 0x1202, - CustomBase = 0x8000 -}; - -/// Values of CapType::ClearBuffers. -enum class ClearBuffers : UInt16 { - Auto = 0, - Clear = 1, - NoClear = 2 -}; - -/// Values of CapType::IPlanarChunky. -enum class ColorFormat : UInt16 { - Chunky = 0, - Planar = 1 -}; - -typedef ColorFormat PlanarChunky; - -/// Values of CapType::ICompression. -/// Also used in ImageInfo and ImageMemXfer. -enum class Compression : UInt16 { - None = 0, - PackBits = 1, - Group31D = 2, - Group31DEol = 3, - Group32D = 4, - Group4 = 5, - Jpeg = 6, - Lzw = 7, - JBig = 8, - Png = 9, - Rle4 = 10, - Rle8 = 11, - BitFields = 12, - Ziz = 13, - Jpeg2000 = 14, - DontCare = 0xFFFF -}; - -/// Countries for Version. -enum class Country : UInt16 { - Afghanistan = 1001, - Algeria = 213, - AmericanSamoa = 684, - Andorra = 033, - Angola = 1002, - Anguilla = 8090, - Antigua = 8091, - Argentina = 54, - Aruba = 297, - Ascensioni = 247, - Australia = 61, - Austria = 43, - Bahamas = 8092, - Bahrain = 973, - Bangladesh = 880, - Barbados = 8093, - Belgium = 32, - Belize = 501, - Benin = 229, - Bermuda = 8094, - Bhutan = 1003, - Bolivia = 591, - Botswana = 267, - Britain = 6, - BritVirginIs = 8095, - Brazil = 55, - Brunei = 673, - Bulgaria = 359, - BurkinaFaso = 1004, - Burma = 1005, - Burundi = 1006, - Camaroon = 237, - Canada = 2, - CapeVerdeIs = 238, - CaymanIs = 8096, - CentralAfRep = 1007, - Chad = 1008, - Chile = 56, - China = 86, - ChristmasIs = 1009, - CocosIs = 1009, - Colombia = 57, - Comoros = 1010, - Congo = 1011, - CookIs = 1012, - Costarica = 506, - Cuba = 005, - Cyprus = 357, - Czechoslovakia = 42, - Denmark = 45, - Djibouti = 1013, - Dominica = 8097, - DomincanRep = 8098, - EasterIs = 1014, - Ecuador = 593, - Egypt = 20, - ElSalvador = 503, - EqGuinea = 1015, - Ethiopia = 251, - FalklandIs = 1016, - FaeroeIs = 298, - FijiIslands = 679, - Finland = 358, - France = 33, - FrAntilles = 596, - FrGuiana = 594, - FrPolyneisa = 689, - FutanaIs = 1043, - Gabon = 241, - Gambia = 220, - Germany = 49, - Ghana = 233, - Gibralter = 350, - Greece = 30, - Greenland = 299, - Grenada = 8099, - Grenedines = 8015, - Guadeloupe = 590, - Guam = 671, - GuantanamoBay = 5399, - Guatemala = 502, - Guinea = 224, - GuineaBissau = 1017, - Guyana = 592, - Haiti = 509, - Honduras = 504, - HongKong = 852, - Hungary = 36, - Iceland = 354, - India = 91, - Indonesia = 62, - Iran = 98, - Iraq = 964, - Ireland = 353, - Israel = 972, - Italy = 39, - IvoryCoast = 225, - Jamaica = 8010, - Japan = 81, - Jordan = 962, - Kenya = 254, - Kiribati = 1018, - Korea = 82, - Kuwait = 965, - Laos = 1019, - Lebanon = 1020, - Liberia = 231, - Libya = 218, - Liechtenstein = 41, - Luxenbourg = 352, - Macao = 853, - Madagascar = 1021, - Malawi = 265, - Malaysia = 60, - Maldives = 960, - Mali = 1022, - Malta = 356, - MarshallIs = 692, - Mauritania = 1023, - Mauritius = 230, - Mexico = 3, - Micronesia = 691, - Miquelon = 508, - Monaco = 33, - Mongolia = 1024, - Montserrat = 8011, - Morocco = 212, - Mozambique = 1025, - Namibia = 264, - Nauru = 1026, - Nepal = 977, - Netherlands = 31, - NethAntilles = 599, - Nevis = 8012, - NewCaledonia = 687, - NewZealand = 64, - Nicaragua = 505, - Niger = 227, - Nigeria = 234, - Niue = 1027, - Norfolki = 1028, - Norway = 47, - Oman = 968, - Pakistan = 92, - Palau = 1029, - Panama = 507, - Paraguay = 595, - Peru = 51, - Phillippines = 63, - PitcairnIs = 1030, - PNewGuinea = 675, - Poland = 48, - Portugal = 351, - Qatar = 974, - Reunioni = 1031, - Romania = 40, - Rwanda = 250, - Saipan = 670, - SanMarino = 39, - SaoTome = 1033, - SaudiArabia = 966, - Senegal = 221, - Seychellesis = 1034, - SierraLeone = 1035, - Singapore = 65, - SolomonIs = 1036, - Somali = 1037, - SouthAfrica = 27, - Spain = 34, - SriLanka = 94, - StHelena = 1032, - StKitts = 8013, - StLucia = 8014, - StPierre = 508, - StVincent = 8015, - Sudan = 1038, - Suriname = 597, - Swaziland = 268, - Sweden = 46, - Switzerland = 41, - Syria = 1039, - Taiwan = 886, - Tanzania = 255, - Thailand = 66, - Tobago = 8016, - Togo = 228, - Tongais = 676, - Trinidad = 8016, - Tunisia = 216, - Turkey = 90, - TurksCaicos = 8017, - Tuvalu = 1040, - Uganda = 256, - Ussr = 7, - UaEmirates = 971, - UnitedKingdom = 44, - Usa = 1, - Uruguay = 598, - Vanuatu = 1041, - VaticanCity = 39, - Venezuela = 58, - Wake = 1042, - WallisIs = 1043, - WesternSahara = 1044, - WesternSamoa = 1045, - Yemen = 1046, - Yugoslavia = 38, - Zaire = 243, - Zambia = 260, - Zimbabwe = 263, - Albania = 355, - Armenia = 374, - Azerbaijan = 994, - Belarus = 375, - BosniaHerzgo = 387, - Cambodia = 855, - Croatia = 385, - CzechRepublic = 420, - DiegoGarcia = 246, - Eritrea = 291, - Estonia = 372, - Georgia = 995, - Latvia = 371, - Lesotho = 266, - Lithuania = 370, - Macedonia = 389, - MayotteIs = 269, - Moldova = 373, - Myanmar = 95, - NorthKorea = 850, - Puertorico = 787, - Russia = 7, - Serbia = 381, - Slovakia = 421, - Slovenia = 386, - SouthKorea = 82, - Ukraine = 380, - UsVirginIs = 340, - Vietnam = 84 -}; - -/// Data group for distinguishing different categories of TWAIN operations. -enum class DataGroup : UInt32 { - Control = 0x0001L, - Image = 0x0002L, - Audio = 0x0004L -}; - -typedef DataGroup DG; - -static constexpr inline UInt32 operator~(DataGroup g) noexcept{ - return ~static_cast(g); -} - -static constexpr inline UInt32 operator|(DataGroup a, DataGroup b) noexcept{ - return static_cast(a) | static_cast(b); -} - -static constexpr inline UInt32 operator|(DataGroup a, UInt32 b) noexcept{ - return static_cast(a) | b; -} - -static constexpr inline UInt32 operator&(DataGroup a, DataGroup b) noexcept{ - return static_cast(a) & static_cast(b); -} - -static constexpr inline UInt32 operator&(UInt32 a, DataGroup b) noexcept{ - return static_cast(a) & b; -} - - -/// Values of CapType::IAutoDiscardBlankPages. -enum class DiscardBlankPages : Int32 { - Disabled = -2, - Auto = -1 -}; - -static constexpr inline DiscardBlankPages discardBytes(Int32 value) noexcept{ - return static_cast(value); -} - -/// Values of CapType::DoubleFeedDetection. -enum class DoubleFeedDetection : UInt16 { - Ultrasonic = 0, - ByLength = 1, - Infrared = 2, -}; - -/// Values of CapType::DoubleFeedDetectionResponse. -enum class DoubleFeedResponse : UInt16 { - Stop = 0, - StopAndWait = 1, - Sound = 2, - DoNotImprint = 3 -}; - -/// Values of CapType::DoubleFeedDetectionSensitivity. -enum class DoubleFeedSensitivity : UInt16 { - Low = 0, - Medium = 1, - High = 2 -}; - -/// Values of CapType::Duplex. -enum class Duplex : UInt16 { - None = 0, - OnePass = 1, - TwoPass = 2 -}; - -/// Values for CapType::FeederAlignment. -enum class FeederAlignment : UInt16 { - None = 0, - Left = 1, - Center = 2, - Right = 3 -}; - -/// Values for CapType::FeederOrder. -enum class FeederOrder : UInt16 { - FirstPageFirst = 0, - LastPageFirst = 1 -}; - - -/// Values for CapType::FeederPocket. -enum class FeederPocket : UInt16 { - PError = 0, - P1 = 1, - P2 = 2, - P3 = 3, - P4 = 4, - P5 = 5, - P6 = 6, - P7 = 7, - P8 = 8, - P9 = 9, - P10 = 10, - P11 = 11, - P12 = 12, - P13 = 13, - P14 = 14, - P15 = 15, - P16 = 16 -}; - -/// Values for CapType::IFeederType. -enum class FeederType : UInt16 { - General = 0, - Photo = 1, -}; - -/// Values for CapType::IFilmType. -enum class FilmType : UInt16 { - Positive = 0, - Negative = 1 -}; - -/// Values for CapType::IFilter. -enum class Filter : UInt16 { - Red = 0, - Green = 1, - Blue = 2, - None = 3, - White = 4, - Cyan = 5, - Magenta = 6, - Yellow = 7, - Black = 8 -}; - -/// Values for CapType::IFlashUsed2 and DeviceEvent.flash. -enum class Flash : UInt16 { // Capability->UInt16, DeviceEvent->UInt32 - None = 0, - Off = 1, - On = 2, - Auto = 3, - RedEye = 4 -}; - -/// Values for CapType::IFlipRotation. -enum class FlipRotation : UInt16 { - Book = 0, - Fanfold = 1 -}; - -/// Values for CapType::PrinterFontStyle -enum class FontStyle : UInt16 { - Normal = 0, - Bold = 1, - Italic = 2, - LargeSize = 3, - SmallSize = 4 -}; - -/// Values for CapType::IIccProfile. -enum class IccProfile : UInt16 { - None = 0, - Link = 1, - Embed = 2 -}; - -/// Values for CapType::IImageFileFormat. -enum class ImageFileFormat : UInt16 { - Tiff = 0, - Pict = 1, - Bmp = 2, - Xbm = 3, - Jfif = 4, - Fpx = 5, - TiffMulti = 6, - Png = 7, - Spiff = 8, - Exif = 9, - Pdf = 10, - Jp2 = 11, - Jpx = 13, - Dejavu = 14, - PdfA = 15, - PdfA2 = 16 -}; - -/// Values for CapType::IImageFilter. -enum class ImageFilter : UInt16 { - None = 0, - Auto = 1, - LowPass = 2, - BandPass = 3, - HighPass = 4, - Text = 3, - FineLine = 4 -}; - -/// Values of CapType::IImageMerge. -enum class ImageMerge : UInt16 { - None = 0, - FrontOnTop = 1, - FrontOnBottom = 2, - FrontOnLeft = 3, - FrontOnRight = 4 -}; - -/// Values of CapType::PrinterIndexTrigger. -enum class IndexTrigger : UInt16 { - Page = 0, - Patch1 = 1, - Patch2 = 2, - Patch3 = 3, - Patch4 = 4, - PatchT = 5, - Patch6 = 6 -}; - -/// Values of CapType::IndicatorsMode. -enum class IndicatorsMode : UInt16 { - Info = 0, - Warning = 1, - Error = 2, - Warmup = 3 -}; - -/// Values of CapType::JobControl. -enum class JobControl : UInt16 { - None = 0, - InclSepContScan = 1, - InclSepStopScan = 2, - ExclSepContScan = 3, - ExclSepStopScap = 4 -}; - -/// Values of CapType::IJpegQuality. -enum class JpegQuality : Int16 { - Unknown = -4, - Low = -3, - Medium = -2, - High = -1 -}; - -static constexpr inline JpegQuality jpegQuality(Int16 value) noexcept{ - return static_cast(value); -} - - -/// Values of CapType::IJpegSubSampling. -enum class JpegSubSampling : UInt16 { - Jp444Ycbcr = 0, - Jp444Rgb = 1, - Jp422 = 2, - Jp421 = 3, - Jp411 = 4, - Jp420 = 5, - Jp410 = 6, - Jp311 = 7 -}; - -/// Values of CapType::Language and Version structure. -enum class Language : UInt16 { - UserLocale = 0xFFFF, - Afrikaans = 14, - Albania = 15, - Arabic = 16, - ArabicAlgeria = 17, - ArabicBahrain = 18, - ArabicEgypt = 19, - ArabicIraq = 20, - ArabicJordan = 21, - ArabicKuwait = 22, - ArabicLebanon = 23, - ArabicLibya = 24, - ArabicMorocco = 25, - ArabicOman = 26, - ArabicQatar = 27, - ArabicSaudiArabia = 28, - ArabicSyria = 29, - ArabicTunisia = 30, - ArabicUae = 31, - ArabicYemen = 32, - Basque = 33, - ByeloRussian = 34, - Bulgarian = 35, - Catalan = 36, - Chinese = 37, - ChineseHongKong = 38, - ChinesePrc = 39, - ChineseSingapore = 40, - ChineseSimplified = 41, - ChineseTaiwan = 42, - ChineseTraditional = 43, - Croatia = 44, - Czech = 45, - Danish = 0, - Dutch = 1, - DutchBelgian = 46, - English = 2, - EnglishAustralian = 47, - EnglishCanadian = 48, - EnglishIreland = 49, - EnglishNewZealand = 50, - EnglishSouthAfrica = 51, - EnglishUk = 52, - EnglishUsa = 13, - Estonian = 53, - Faeroese = 54, - Farsi = 55, - Finnish = 4, - French = 5, - FrenchBelgian = 56, - FrenchCanadian = 3, - FrenchLuxembourg = 57, - FrenchSwiss = 58, - German = 6, - GermanAustrian = 59, - GermanLuxembourg = 60, - GermanLiechtenstein = 61, - GermanSwiss = 62, - Greek = 63, - Hebrew = 64, - Hungarian = 65, - Icelandic = 7, - Indonesian = 66, - Italian = 8, - ItalianSwiss = 67, - Japanese = 68, - Korean = 69, - KoreanJohab = 70, - Latvian = 71, - Lithuanian = 72, - Norwegian = 9, - NorwegianBokmal = 73, - NorwegianNynorsk = 74, - Polish = 75, - Portuguese = 10, - PortugueseBrazil = 76, - Romanian = 77, - Russian = 78, - SerbianLatin = 79, - Slovak = 80, - Slovenian = 81, - Spanish = 11, - SpanishMexican = 82, - SpanishModern = 83, - Swedish = 12, - Thai = 84, - Turkish = 85, - Ukranian = 86, - Assamese = 87, - Bengali = 88, - Bihari = 89, - Bodo = 90, - Dogri = 91, - Gujarati = 92, - Haryanvi = 93, - Hindi = 94, - Kannada = 95, - Kashmiri = 96, - Malayalam = 97, - Marathi = 98, - Marwari = 99, - Meghalayan = 100, - Mizo = 101, - Naga = 102, - Orissi = 103, - Punjabi = 104, - Pushtu = 105, - SerbianCyrillic = 106, - Sikkimi = 107, - SwedishFinland = 108, - Tamil = 109, - Telugu = 110, - Tripuri = 111, - Urdu = 112, - Vietnamese = 113 -}; - -/// Values of CapType::ILightPath. -enum class LightPath : UInt16 { - Reflective = 0, - Transmissive = 1 -}; - -/// Values of CapType::ILightSource. -enum class LightSource : UInt16 { - Red = 0, - Green = 1, - Blue = 2, - None = 3, - White = 4, - Uv = 5, - Ir = 6 -}; - -/// Values for CapType::IMirror. -enum class Mirror : UInt16 { - None = 0, - Vertical = 1, - Horizontal = 2 -}; - -/// Values of possible actions of TWAIN operations. -enum class Msg : UInt16 { - Null = 0x0000, - Get = 0x0001, - GetCurrent = 0x0002, - GetDefault = 0x0003, - GetFirst = 0x0004, - GetNext = 0x0005, - Set = 0x0006, - Reset = 0x0007, - QuerySupport = 0x0008, - GetHelp = 0x0009, - GetLabel = 0x000a, - GetLabelEnum = 0x000b, - SetConstraint = 0x000c, - XferReady = 0x0101, - CloseDsReq = 0x0102, - CloseDsOk = 0x0103, - DeviceEvent = 0x0104, - OpenDsm = 0x0301, - CloseDsm = 0x0302, - OpenDs = 0x0401, - CloseDs = 0x0402, - UserSelect = 0x0403, - DisableDs = 0x0501, - EnableDs = 0x0502, - EnableDsUiOnly = 0x0503, - ProcessEvent = 0x0601, - EndXfer = 0x0701, - StopFeeder = 0x0702, - ChangeDir = 0x0801, - CreateDir = 0x0802, - Delete = 0x0803, - FormatMedia = 0x0804, - GetClose = 0x0805, - GetFirstFile = 0x0806, - GetInfo = 0x0807, - GetNextFile = 0x0808, - Rename = 0x0809, - Copy = 0x080A, - AutomaticCaptureDir = 0x080B, - PassThrough = 0x0901, - RegisterCallback = 0x0902, - ResetAll = 0x0A01, - CustomBase = 0x8000 -}; - -/// Capability action support flags. -enum class MsgSupport : Int32 { - Get = 0x0001, - Set = 0x0002, - GetDefault = 0x0004, - GetCurrent = 0x0008, - Reset = 0x0010, - SetConstraint = 0x0020, - GetHelp = 0x0100, - GetLabel = 0x0200, - GetLabelEnum = 0x0400 -}; - -static inline constexpr MsgSupport operator|(MsgSupport a, MsgSupport b){ - return static_cast(static_cast(a) | static_cast(b)); -} - -static inline constexpr MsgSupport operator&(MsgSupport a, MsgSupport b){ - return static_cast(static_cast(a) & static_cast(b)); -} - -static inline constexpr MsgSupport operator^(MsgSupport a, MsgSupport b){ - return static_cast(static_cast(a) ^ static_cast(b)); -} - -/// Action support flags, nothing supported. -static constexpr const MsgSupport msgSupportEmpty = static_cast(0); - -/// Action support flags, all `get` actions. -static constexpr const MsgSupport msgSupportGetAll = MsgSupport::Get | MsgSupport::GetDefault | MsgSupport::GetCurrent; - -/// Action support flags, all `get` actions, `set` and `reset`. -static constexpr const MsgSupport msgSupportGetAllSetReset = msgSupportGetAll | MsgSupport::Set | MsgSupport::Reset; - -/// Values for CapType::INoiseFilter. -enum class NoiseFilter : UInt16 { - None = 0, - Auto = 1, - LonePixel = 2, - MajorityRule = 3 -}; - -/// Values for CapType::IOrientation. -enum class Orientation : UInt16 { - Rot0 = 0, - Rot90 = 1, - Rot180 = 2, - Rot270 = 3, - Portrait = 0, - Landscape = 3, - Auto = 4, - AutoText = 5, - AutoPicture = 6 -}; - -/// Values for CapType::IOverscan. -enum class OverScan : UInt16 { - None = 0, - Auto = 1, - TopBottom = 2, - LeftRight = 3, - All = 4 -}; - -/// Values for CapType::PaperHandling. -enum class PaperHandling : UInt16 { - Normal = 0, - Fragile = 1, - Thick = 2, - TriFold = 3, - Photograph = 4 -}; - -/// Values for CapType::ISupportedSizes. -enum class PaperSize : UInt16 { - None = 0, - A4 = 1, - JisB5 = 2, - UsLetter = 3, - UsLegal = 4, - A5 = 5, - IsoB4 = 6, - IsoB6 = 7, - UsLedger = 9, - UsExecutive = 10, - A3 = 11, - IsoB3 = 12, - A6 = 13, - C4 = 14, - C5 = 15, - C6 = 16, - Ps4A0 = 17, // 4A0 - Ps2A0 = 18, // 2A0 - A0 = 19, - A1 = 20, - A2 = 21, - A7 = 22, - A8 = 23, - A9 = 24, - A10 = 25, - IsoB0 = 26, - IsoB1 = 27, - IsoB2 = 28, - IsoB5 = 29, - IsoB7 = 30, - IsoB8 = 31, - IsoB9 = 32, - IsoB10 = 33, - JisB0 = 34, - JisB1 = 35, - JisB2 = 36, - JisB3 = 37, - JisB4 = 38, - JisB6 = 39, - JisB7 = 40, - JisB8 = 41, - JisB9 = 42, - JisB10 = 43, - C0 = 44, - C1 = 45, - C2 = 46, - C3 = 47, - C7 = 48, - C8 = 49, - C9 = 50, - C10 = 51, - UsStatement = 52, - BusinessCard = 53, - MaxSize = 54 -}; - -/// Values for CapType::IPixelFlavor, CapType::IPixelFlavorCodes, InfoId::PixelFlavor. -/// Chocolate - pixel represents darkest data. -/// Vanilla - pixel represents lightest data. -enum class PixelFlavor : UInt16 { - Chocolate = 0, - Vanilla = 1 -}; - -/// Values for CapType::IPixelType, ImageInfo. -enum class PixelType : UInt16 { - BlackWhite = 0, - Gray = 1, - Rgb = 2, - Palette = 3, - Cmy = 4, - Cmyk = 5, - Yuv = 6, - Yuvk = 7, - CieXyz = 8, - Lab = 9, - SRgb = 10, - ScRgb = 11, - Infrared = 16 -}; - -/// Values for CapType::PowerSupply. -enum class PowerSupply : UInt16 { // Capability->UInt16, DeviceEvent->Int32 - External = 0, - Battery = 1, -}; - -/// Values for CapType::Printer. -enum class Printer : UInt16 { - ImprinterTopBefore = 0, - ImprinterTopAfter = 1, - ImprinterBottomBefore = 2, - ImprinterBottomAfter = 3, - EndorserTopBefore = 4, - EndorserTopAfter = 5, - EndorserBottomBefore = 6, - EndorserBottomAfter = 7 -}; - -/// Values for CapType::PrinterMode. -enum class PrinterMode : UInt16 { - SingleString = 0, - MultiString = 1, - CompoundString = 2 -}; - -enum class ReturnCode : UInt16 { - Success = 0, - Failure = 1, - CheckStatus = 2, - Cancel = 3, - DsEvent = 4, - NotDsEvent = 5, - XferDone = 6, - EndOfList = 7, - InfoNotSupported = 8, - DataNotAvailable = 9, - Busy = 10, - ScannerLocked = 11, - - CustomBase = 0x8000 -}; - -typedef ReturnCode RC; - -static inline constexpr bool success(ReturnCode rc) noexcept{ - return rc == RC::Success; -} - - -/// Values for CapType::IBarCodeSearchMode. -enum class SearchMode : UInt16 { - Horizontal = 0, - Vertical = 1, - HorizVert = 2, - VertHoriz = 3 -}; - -/// Values for CapType::Segmented. -enum class Segmented : UInt16 { - None = 0, - Auto = 1, - Manual = 2 -}; - -/// TWAIN manager states. -enum class DsmState : UInt16 { - PreSession = 1, - Loaded = 2, - Open = 3 -}; - -/// TWAIN source states. -enum class DsState : UInt16 { - Closed = 3, - Open = 4, - Enabled = 5, - XferReady = 6, - Xferring = 7 -}; - -/// Values for CapType::IUnits. -enum class Unit : UInt16 { - Inches = 0, - CentiMetres = 1, - Picas = 2, - Points = 3, - Twips = 4, - Pixels = 5, - MilliMetres = 6 -}; - -/// Values for CapType::IXferMech, CapType::AXferMech. -enum class XferMech : UInt16 { - Native = 0, - File = 1, - Memory = 2, - MemFile = 4, -}; - - -/// Type of the extended information. -enum class InfoId : UInt16 { - BarCodeX = 0x1200, - BarCodeY = 0x1201, - BarCodeText = 0x1202, - BarCodeType = 0x1203, - DeShadeTop = 0x1204, - DeShadeLeft = 0x1205, - DeShadeHeight = 0x1206, - DeShadeWidth = 0x1207, - DeShadeSize = 0x1208, - SpecklesRemoved = 0x1209, - HorzLineXCoord = 0x120A, - HorzLineYCoord = 0x120B, - HorzLineLength = 0x120C, - HorzLineThickness = 0x120D, - VertLineXCoord = 0x120E, - VertLineYCoord = 0x120F, - VertLineLength = 0x1210, - VertLineThickness = 0x1211, - PatchCode = 0x1212, - EndorsedText = 0x1213, - FormConfidence = 0x1214, - FormTemplateMatch = 0x1215, - FormTemplatePageMatch = 0x1216, - FormHorzDocOffset = 0x1217, - FormVertDocOffset = 0x1218, - BarCodeCount = 0x1219, - BarCodeConfidence = 0x121A, - BarCodeRotation = 0x121B, - BarCodeTextLength = 0x121C, - DeShadeCount = 0x121D, - DeShadeBlackCountOld = 0x121E, - DeShadeBlackCountNew = 0x121F, - DeShadeBlackRlMin = 0x1220, - DeShadeBlackRlMax = 0x1221, - DeShadeWhiteCountOld = 0x1222, - DeShadeWhiteCountNew = 0x1223, - DeShadeWhiteRlMin = 0x1224, - DeShadEWhiteRlAve = 0x1225, - DeShadeWhiteRlMax = 0x1226, - BlackSpecklesRemoved = 0x1227, - WhiteSpecklesRemoved = 0x1228, - HorzLineCount = 0x1229, - VertLineCount = 0x122A, - DeskewStatus = 0x122B, - SkewOriginalAngle = 0x122C, - SkewFinalAngle = 0x122D, - SkewConfidence = 0x122E, - SkewWindowX1 = 0x122F, - SkewWindowY1 = 0x1230, - SkewWindowX2 = 0x1231, - SkewWindowY2 = 0x1232, - SkewWindowX3 = 0x1233, - SkewWindowY3 = 0x1234, - SkewWindowX4 = 0x1235, - SkewWindowY4 = 0x1236, - BookName = 0x1238, - ChapterNumber = 0x1239, - DocumentNumber = 0x123A, - PageNumber = 0x123B, - Camera = 0x123C, - FrameNumber = 0x123D, - Frame = 0x123E, - PixelFlavor = 0x123F, - IccProfile = 0x1240, - LastSegment = 0x1241, - SegmentNumber = 0x1242, - MagData = 0x1243, - MagType = 0x1244, - PageSide = 0x1245, - FileSystemSource = 0x1246, - ImageMerged = 0x1247, - MagDataLength = 0x1248, - PaperCount = 0x1249, - PrinterText = 0x124A -}; - -/// Values for InfoId::BarCodeRotation. -enum class BarCodeRotation : UInt16 { - Rot0 = 0, - Rot90 = 1, - Rot180 = 2, - Rot270 = 3, - RotUnknown = 4 -}; - -/// Values for InfoId::PageSide. -enum class PageSide : UInt16 { - Top = 1, - Bottom = 2 -}; - -/// Values for InfoId::DeskewStatus. -enum class DeskewStatus : UInt16 { - Success = 0, - ReportOnly = 1, - Fail = 2, - Disabled = 3 -}; - -/// Values for InfoId::MagType. -enum class MagType : UInt16 { - Micr = 0, - Raw = 1, - Invalid = 2 -}; - -/// Values for InfoId::PatchCode. -enum class PatchCode : UInt16 { - P1 = 0, - P2 = 1, - P3 = 2, - P4 = 3, - P6 = 4, - PT = 5 -}; - -} - -#endif // TWPP_DETAIL_FILE_ENUMS_HPP - diff --git a/twain/twain/twpp/env.hpp b/twain/twain/twpp/env.hpp deleted file mode 100644 index fae3d4b..0000000 --- a/twain/twain/twpp/env.hpp +++ /dev/null @@ -1,356 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2017 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_ENV_HPP -#define TWPP_DETAIL_FILE_ENV_HPP - -// ============= -// Twpp specific - -namespace Twpp { - -namespace Detail { - -enum { - ProtoMajor = 2, - ProtoMinor = 3, - Dsm2 = 0x10000000L, - App2 = 0x20000000L, - Ds2 = 0x40000000L -}; - -} - -} - -#if defined(TWPP_IS_DS) -# define TWPP_DETAIL_IS_DS 1 -#else -# define TWPP_DETAIL_IS_DS 0 -#endif - - -// =========== -// OS specific - -// Windows -#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) -# define TWPP_DETAIL_OS_WIN 1 -# if defined(WIN64) || defined(_WIN64) -# define TWPP_DETAIL_OS_WIN64 1 -# else -# define TWPP_DETAIL_OS_WIN32 1 -# endif -# if !defined(WIN32_LEAN_AND_MEAN) -# define WIN32_LEAN_AND_MEAN -# endif -# if !defined(NOMINMAX) -# define NOMINMAX -# endif -extern "C" { -# include -} -# define TWPP_DETAIL_CALLSTYLE PASCAL -# define TWPP_DETAIL_EXPORT __declspec(dllexport) -namespace Twpp { - -namespace Detail { - -typedef HANDLE RawHandle; - - -namespace DsmLibOs { - -typedef HMODULE Handle; -static constexpr const Handle nullHandle = nullptr; - -template -static inline T resolve(Handle h) noexcept{ - return reinterpret_cast(::GetProcAddress(h, "DSM_Entry")); -} - -# if defined(TWPP_DETAIL_OS_WIN32) -static inline Handle load(bool old) noexcept{ - if (old){ - auto h = ::LoadLibraryA("TWAIN_32.dll"); - if (!h){ - h = ::LoadLibraryA("TWAINDSM.dll"); - } - - return h; - } else { - auto h = ::LoadLibraryA("TWAINDSM.dll"); - if (!h){ - h = ::LoadLibraryA("TWAIN_32.dll"); - } - - return h; - } -} -# else -static inline Handle load(bool) noexcept{ - return ::LoadLibraryA("TWAINDSM.dll"); -} -# endif - -static inline void unload(Handle h) noexcept{ - ::FreeLibrary(h); -} - -} // namespace DsmLibOs - -} // namespace Detail - -} // namespace Twpp - - -// Mac OS -#elif defined(__APPLE__) -# pragma message "No testing has been done on this platform, this framework might not work correctly." -# define TWPP_DETAIL_OS_MAC 1 -# include -extern "C" { -# include -# include -# include -# include -# include -} -# define TWPP_DETAIL_CALLSTYLE pascal -namespace Twpp { - -namespace Detail { - -typedef Handle RawHandle; - - -namespace DsmLibOs { - -typedef void* Handle; -static constexpr const Handle nullHandle = nullptr; - -template -static inline T resolve(Handle h) noexcept{ - return reinterpret_cast(::dlsym(h, "DSM_Entry")); -} - -static inline Handle load(bool) noexcept{ - return ::dlopen("/System/Library/Frameworks/TWAIN.framework/TWAIN", RTLD_LAZY); -} - -static inline void unload(Handle h) noexcept{ - ::dlclose(h); -} - -} // namespace DsmLibOs - -template -struct MacStatic { - - static const ::Class g_autoreleasePool; - static const ::SEL g_release; - static const ::SEL g_alloc; - static const ::SEL g_init; - - static const ::SEL g_nextEvent; - static const ::SEL g_postEvent; - static const ::SEL g_sendEvent; - static const ::id g_app; - static const ::id g_distantFuture; - - static const ::Class g_event; - static const ::SEL g_otherEventWithType; - -}; - -template const ::Class MacStatic::g_autoreleasePool = objc_getClass("NSAutoreleasePool"); -template const ::SEL MacStatic::g_release = sel_registerName("release"); -template const ::SEL MacStatic::g_alloc = sel_registerName("alloc"); -template const ::SEL MacStatic::g_init = sel_registerName("init"); - -template const ::SEL MacStatic::g_nextEvent = sel_registerName("nextEventMatchingMask:untilDate:inMode:dequeue:"); -template const ::SEL MacStatic::g_postEvent = sel_registerName("postEvent:atStart:"); -template const ::SEL MacStatic::g_sendEvent = sel_registerName("sendEvent:"); -template const ::id MacStatic::g_app = objc_msgSend(reinterpret_cast<::id>(objc_getClass("NSApplication")), sel_registerName("sharedApplication")); -template const ::id MacStatic::g_distantFuture = objc_msgSend(reinterpret_cast<::id>(objc_getClass("NSDate")), sel_registerName("distantFuture")); - -template const ::Class MacStatic::g_event = objc_getClass("NSEvent"); -template const ::SEL MacStatic::g_otherEventWithType = sel_registerName("otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:"); - -class NSAutoreleasePool { - -public: - NSAutoreleasePool() noexcept : - m_id(createPool()) {} - - ~NSAutoreleasePool(){ - release(); - } - - NSAutoreleasePool(const NSAutoreleasePool&) = delete; - NSAutoreleasePool& operator=(const NSAutoreleasePool&) = delete; - - NSAutoreleasePool(NSAutoreleasePool&& o) noexcept : - m_id(o.m_id){ - - o.m_id = nullptr; - } - - NSAutoreleasePool& operator=(NSAutoreleasePool&& o) noexcept{ - if (this != &o){ - release(); - std::swap(m_id, o.m_id); - } - - return *this; - } - - void release() noexcept{ - if (m_id != nullptr){ - objc_msgSend(m_id, MacStatic::g_release); - m_id = nullptr; - } - } - -private: - static ::id createPool() noexcept{ - auto poolId = objc_msgSend(reinterpret_cast<::id>(MacStatic::g_autoreleasePool), MacStatic::g_alloc); - return objc_msgSend(poolId, MacStatic::g_init); - } - - ::id m_id; - -}; - -namespace NSLoop { - -static constexpr ::NSUInteger NSAnyEventMask = std::numeric_limits<::NSUInteger>::max(); -static constexpr ::NSUInteger NSApplicationDefined = 15; - -static void processEvent() noexcept{ - auto event = objc_msgSend(MacStatic::g_app, MacStatic::g_nextEvent, NSAnyEventMask, MacStatic::g_distantFuture, kCFRunLoopDefaultMode, YES); - objc_msgSend(MacStatic::g_app, MacStatic::g_sendEvent, event); -} - -static void postDummy() noexcept{ - auto event = objc_msgSend(reinterpret_cast<::id>(MacStatic::g_event), MacStatic::g_otherEventWithType, NSApplicationDefined, nullptr, 1, 0.0, 0, nullptr, static_cast(0), 0, 0); - objc_msgSend(MacStatic::g_app, MacStatic::g_postEvent, event, NO); -} - -} // namespace NSLoop - -} // namespace Detail - -} // namespace Twpp - -// Linux -#elif defined(__linux__) -# warning "No testing has been done on this platform, this framework might not work correctly." -# define TWPP_DETAIL_OS_LINUX 1 -extern "C" { -# include -} -# define TWPP_DETAIL_CALLSTYLE -namespace Twpp { - -namespace Detail { - -typedef void* RawHandle; - - -namespace DsmLibOs { - -typedef void* Handle; -static constexpr const Handle nullHandle = nullptr; - -template -static inline T resolve(Handle h) noexcept{ - return reinterpret_cast(::dlsym(h, "DSM_Entry")); -} - -static inline Handle load(bool) noexcept{ - return ::dlopen("libtwaindsm.so", RTLD_LAZY); -} - -static inline void unload(Handle h) noexcept{ - ::dlclose(h); -} - -} // namespace DsmLibOs - -} // namespace Detail - -} // namespace Twpp - -// fail everything else -#else -# error "unsupported platform, supports only Windows, Mac OS and Linux" -#endif - - -// ================= -// compiler specific - -// MSVC -#if defined(_MSC_VER) -# define TWPP_DETAIL_PACK_BEGIN \ - __pragma(pack (push, beforeTwpp)) \ - __pragma(pack (2)) -# define TWPP_DETAIL_PACK_END __pragma(pack (pop, beforeTwpp)); - -// GNU or CLang -#elif defined(__GNUC__) || defined(__clang__) -# if defined(TWPP_DETAIL_OS_MAC) -# define TWPP_DETAIL_PACK_BEGIN _Pragma("options align = power") -# define TWPP_DETAIL_PACK_END _Pragma("options align = reset") -# else -# define TWPP_DETAIL_PACK_BEGIN \ - _Pragma("pack (push, beforeTwpp)") \ - _Pragma("pack (2)") -# define TWPP_DETAIL_PACK_END _Pragma("pack (pop, beforeTwpp)") -# endif -# if !defined(TWPP_DETAIL_EXPORT) -# define TWPP_DETAIL_EXPORT __attribute__((__visibility__("default"))) -# endif - -// Borland -#elif defined(__BORLAND__) || defined(__BORLANDC__) || defined(__CODEGEARC__) -# define TWPP_DETAIL_PACK_BEGIN _Pragma("option -a2") -# define TWPP_DETAIL_PACK_END _Pragma("option -a") - -// fail everything else -#else -# error "unsupported compiler, please define your own TWPP_DETAIL_PACK_BEGIN and TWPP_DETAIL_PACK_END and possibly TWPP_DETAIL_EXPORT in twpp/env.hpp and send me your patch" -#endif - - -#if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1900) // msvc2015 -# error "C++11 or later is required" -#endif - - -#endif // TWPP_DETAIL_FILE_ENV_HPP - diff --git a/twain/twain/twpp/event.hpp b/twain/twain/twpp/event.hpp deleted file mode 100644 index 1aff32d..0000000 --- a/twain/twain/twpp/event.hpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_EVENT_HPP -#define TWPP_DETAIL_FILE_EVENT_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Loop event on Windows. -/// Used while waiting for transfer. -/// See manual for more info. -class Event { - -public: - constexpr Event() noexcept : - m_event(nullptr), m_msg(Msg::Null){} - - constexpr Event(void* event, Msg msg) noexcept : - m_event(event), m_msg(msg){} - - constexpr void* event() const noexcept{ - return m_event; - } - - void setEvent(void* event) noexcept{ - m_event = event; - } - - constexpr Msg message() const noexcept{ - return m_msg; - } - - void setMessage(Msg msg) noexcept{ - m_msg = msg; - } - -private: - void* m_event; - Msg m_msg; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_EVENT_HPP diff --git a/twain/twain/twpp/exception.hpp b/twain/twain/twpp/exception.hpp deleted file mode 100644 index 3aa34dc..0000000 --- a/twain/twain/twpp/exception.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef TWPP_DETAIL_FILE_EXCEPTION_HPP -#define TWPP_DETAIL_FILE_EXCEPTION_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -/// Base class of TWPP exceptions. -class Exception : public std::exception { - -public: - virtual const char* what() const noexcept override{ - return "General TWPP error."; - } - -}; - -/// Invalid type exception. -/// Used when an invalid or unsupported type identifier is used. -class TypeException : public Exception { - -public: - virtual const char* what() const noexcept override{ - return "Invalid type."; - } - -}; - -/// Value out of valid range exception. -class RangeException : Exception { - -public: - virtual const char* what() const noexcept override{ - return "Value out of allowed range."; - } - -}; - -} - -#endif // TWPP_DETAIL_FILE_EXCEPTION_HPP - diff --git a/twain/twain/twpp/extimageinfo.hpp b/twain/twain/twpp/extimageinfo.hpp deleted file mode 100644 index f2a3246..0000000 --- a/twain/twain/twpp/extimageinfo.hpp +++ /dev/null @@ -1,547 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_EXTIMAGEINFO_HPP -#define TWPP_DETAIL_FILE_EXTIMAGEINFO_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -/// Mapping of info type to type identifier and data type. -template struct Ext {}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef BarCodeRotation DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::Handle; typedef char DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef BarCodeType DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef PatchCode DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef DeskewStatus DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::Frame; typedef Frame DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt16; typedef PixelFlavor DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt16; typedef MagType DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::Bool; typedef Bool DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::Str255; typedef char DataType;}; // NOTE: InfoId::MagData may also contain Handle -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; -template<> struct Ext {static constexpr const Type twty = Type::UInt16; typedef PageSide DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::UInt32; typedef UInt32 DataType;}; - -template<> struct Ext {static constexpr const Type twty = Type::Str255; typedef Str255 DataType;}; - -} - -class Info; -class ExtImageInfo; - -namespace Detail { - -static Handle handleItem(Info& info) noexcept; - -static void deleteInfo(Info& info) noexcept; - -} - -TWPP_DETAIL_PACK_BEGIN -/// Extended image information entry. -class Info { - - friend class ExtImageInfo; - friend Handle Detail::handleItem(Info& info) noexcept; - friend void Detail::deleteInfo(Info& info) noexcept; - static constexpr const UInt32 DATA_HANDLE_THRESHOLD = sizeof(UIntPtr); // NOTE: specification says 4 bytes, yet pointer size makes more sense - -public: - template - class Items { - - friend class Info; - - public: - typedef Detail::MaybeLock Data; - - constexpr Items() noexcept : - m_parent(nullptr){} - - Items(const Items&) = default; - Items& operator=(const Items&) = default; - - Items(Items&&) = default; - Items& operator=(Items&&) = default; - - operator bool() const noexcept{ - return m_data; - } - - Data at(UInt32 i) const{ - if (m_parent->hasDataHandle() && m_parent->type() == Type::Handle){ - return reinterpret_cast(m_data.data())[i]; - } else { - return reinterpret_cast(m_data.data() + i * typeSize(m_parent->type())); - } - } - - Data operator[](UInt32 i) const{ - return at(i); - } - - private: - Items(Info& parent, Detail::MaybeLock data) noexcept : - m_parent(&parent), m_data(data){} - - Info* m_parent; - Detail::MaybeLock m_data; - // [items] <=> !(big and handle) - // [handles]->handles*[items] <=> big and handle (this should teoretically not happen) - - }; - - Info(const Info&) = delete; - Info& operator=(const Info&) = delete; - - Info(Info&&) = delete; - Info& operator=(Info&&) = delete; - - /// Information type ID. - InfoId id() const noexcept{ - return m_infoId; - } - - /// Information data type ID. - Type type() const noexcept{ - return m_itemType; - } - - /// Number of items in this entry. - UInt16 size() const noexcept{ - return m_numItems; - } - - /// Allocates space for the supplied number of items. - /// Allocating handles is not supported. - /// \tparam id Information type ID. Data types are set accordingly. - /// \param count Number of items to allocate. - /// \throw TypeException When `type` is handle or invalid. - /// \throw std::bad_alloc - template - void allocSimple(UInt16 count = 1){ - allocSimple(Detail::Ext::twty, count); - } - - /// Allocates space for the supplied number of items. - /// Allocating handles is not supported. - /// \param type Data type ID. - /// \param count Number of items to allocate. - /// \throw TypeException When `type` is handle or invalid. - /// \throw std::bad_alloc - void allocSimple(Type type, UInt16 count = 1){ - if (type == Type::Handle){ - throw TypeException(); - } - - if (type == m_itemType && count == m_numItems){ - return; - } - - auto itemSize = typeSize(type); - - bool big = hasDataHandle(type, count); - // [items] <=> !big - // handle->[items] <=> big - - Detail::UniqueHandle newItem; - if (big){ - newItem = Detail::alloc(itemSize * count); - } - - Detail::deleteInfo(*this); - - if (big){ - *Detail::alias_cast(&m_item) = newItem.release(); - } - - m_itemType = type; - m_numItems = count; - } - - /// Allocates a single memory area owned by a handle. - /// Info type changes to handle. - /// \param itemSize Number of bytes to allocate. - /// \throw std::bad_alloc - void allocHandle(UInt32 itemSize){ - // handle->[chars] - auto newItem = Detail::UniqueHandle(Detail::alloc(itemSize)); - - Detail::deleteInfo(*this); - *Detail::alias_cast(&m_item) = newItem.release(); - - m_itemType = Type::Handle; - m_numItems = 1; - } - - /// Status of this entry. - ReturnCode returnCode() const noexcept{ - return m_returnCode; - } - - /// Sets status of this entry. - void setReturnCode(ReturnCode rc) noexcept{ - m_returnCode = rc; - } - - /// Returns items contained in this entry. - /// \tparam type ID of the internal data type. - /// \tparam DataType Exported data type. - /// \throw TypeException When types don't match. - template - Items items(){ - if (type != m_itemType || (type != Type::Handle && typeSize(type) != sizeof(DataType))){ - throw TypeException(); - } - - return itemsPriv(); - } - - /// Returns items contained in this entry. - /// \tparam type ID of the internal data type. - /// \throw TypeException When types don't match. - template - Items::Type> items(){ - if (type != m_itemType){ - throw TypeException(); - } - - return itemsPriv::Type>(); - } - - /// Returns items contained in this entry. - /// \tparam id Information type ID. Data types are set accordingly. - /// \throw TypeException When types don't match. - template - Items::DataType> items(){ - if (Detail::Ext::twty != m_itemType){ - throw TypeException(); - } - - return itemsPriv::DataType>(); - } - -private: - bool hasDataHandle() const{ - return hasDataHandle(type(), size()); - } - - static bool hasDataHandle(Type type, UInt16 size){ - return type != Type::DontCare && size * typeSize(type) > DATA_HANDLE_THRESHOLD; - } - - template - Items itemsPriv(){ - bool big = hasDataHandle(); - bool handle = m_itemType == Type::Handle; - - Detail::MaybeLock lock; - if (!big && !handle){ - lock = Detail::alias_cast(&m_item); - } else { - lock = *Detail::alias_cast(&m_item); - } - - return {*this, std::move(lock)}; - } - - template - static bool arrContains(const T(& arr)[len], const T& val) noexcept{ - for (std::size_t i = 0; i < len; i++){ - if (arr[i] == val){ - return true; - } - } - - return false; - } - - InfoId m_infoId; - Type m_itemType; - UInt16 m_numItems; - ReturnCode m_returnCode; - UIntPtr m_item; - // [items] <=> !big and !handle - // handle->[items] <=> big xor handle - // handle->[handles]->handles*[items] <=> big and handle (this should teoretically not happen) - -}; - -namespace Detail { - -static inline Handle handleItem(Info& info) noexcept{ - return Handle(*Detail::alias_cast(&info.m_item)); -} - -static inline void deleteInfo(Info& info) noexcept{ - bool big = isType(info.type()) && info.hasDataHandle(); - bool handle = info.type() == Type::Handle; - - // [items] <=> !big and !handle - // handle->[items] <=> big xor handle - // handle->[handles]->handles*[items] <=> big and handle (this should teoretically not happen) - - if (big && handle){ - Detail::Lock lock(handleItem(info)); - for (UInt16 i = 0; i < info.size(); i++){ - Detail::free(lock.data()[i]); - } - } - - if (big || handle){ - Detail::free(handleItem(info)); - } -} - -struct ExtImageInfoData { - UInt32 m_numInfos; - Info m_infos[1]; -}; - -} - -TWPP_DETAIL_PACK_END -/// Extended image information. -/// Application sends list of info IDs, -/// source sets their data. -class ExtImageInfo { - -public: - typedef Info* iterator; - typedef const Info* const_iterator; - - /// Creates an invalid object. - ExtImageInfo() noexcept {} - - /// Creates a new structure for all supplied info IDs. - /// Sources must not call this constructor, they - /// are required to fill data in existing instance. - /// \param ids List of requested info IDs to be filled in by the source. - ExtImageInfo(std::initializer_list ids) : - m_data(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]()) { - - d()->m_numInfos = static_cast(ids.size()); - - Info* infos = d()->m_infos; - - UInt32 i = 0; - for (auto id : ids) { - auto& info = infos[i]; - i++; - - info.m_infoId = id; - info.m_itemType = Type::DontCare; - } - } - void set_data(const std::list& ids) noexcept { - m_data.reset(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]); - - d()->m_numInfos = static_cast(ids.size()); - - Info* infos = d()->m_infos; - UInt32 i = 0; - for (const auto id : ids) { - auto& info = infos[i]; - i++; - - info.m_infoId = id; - info.m_itemType = Type::DontCare; - } - } - - ExtImageInfo(ExtImageInfo&&) = default; - ExtImageInfo& operator=(ExtImageInfo&&) = default; - - operator bool() const noexcept{ - return isValid(); - } - - bool isValid() const noexcept{ - return static_cast(m_data); - } - - /// Number of requested entries. - UInt32 size() const noexcept{ - assert(isValid()); - return d()->m_numInfos; - } - - /// Information entry. - Info& at(UInt32 i) noexcept{ - assert(isValid()); - return d()->m_infos[i]; - } - - /// Information entry. - const Info& at(UInt32 i) const noexcept{ - assert(isValid()); - return d()->m_infos[i]; - } - - Info& operator[](UInt32 i) noexcept{ - return at(i); - } - - const Info& operator[](UInt32 i) const noexcept{ - return at(i); - } - - - iterator begin() noexcept{ - assert(isValid()); - return d()->m_infos; - } - - const_iterator begin() const noexcept{ - return cbegin(); - } - - const_iterator cbegin() const noexcept{ - assert(isValid()); - return d()->m_infos; - } - - iterator end() noexcept{ - assert(isValid()); - return d()->m_infos + d()->m_numInfos; - } - - const_iterator end() const noexcept{ - return cend(); - } - - const_iterator cend() const noexcept{ - assert(isValid()); - return d()->m_infos + d()->m_numInfos; - } - -private: - Detail::ExtImageInfoData* d() noexcept{ - return reinterpret_cast(m_data.get()); - } - - Detail::ExtImageInfoData* d() const noexcept{ - return reinterpret_cast(m_data.get()); - } - - struct Deleter { - void operator()(char* ptr) noexcept{ - Detail::ExtImageInfoData* data = reinterpret_cast(ptr); - if (data){ - for (UInt32 i = 0; i < data->m_numInfos; i++){ - Detail::deleteInfo(data->m_infos[i]); - } - - delete [] ptr; - } - } - }; - - std::unique_ptr m_data; - -}; - -} - -#endif // TWPP_DETAIL_FILE_EXTIMAGEINFO_HPP - diff --git a/twain/twain/twpp/filesystem.hpp b/twain/twain/twpp/filesystem.hpp deleted file mode 100644 index b7bbc79..0000000 --- a/twain/twain/twpp/filesystem.hpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_FILESYSTEM_HPP -#define TWPP_DETAIL_FILE_FILESYSTEM_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Structure representing device filesystem and operations on it. -class FileSystem { - -public: - /// Type of file. - enum class Type : Int32 { - Camera = 0, - CameraTop = 1, - CameraBottom = 2, - CameraPreview = 3, - Domain = 4, - Host = 5, - Directory = 6, - Image = 7, - Unknown = 8 - }; - - /// Creates uninitialized file system. - constexpr FileSystem() noexcept : - m_context(nullptr), m_recursiveBool(), m_fileType(Type::Camera), m_size(), - m_freeSpace(), m_newImageSize(), m_numberOfFiles(), m_numberOfSnippets(), - m_deviceGroupMask(), m_reserved(){} - - /// Creates file system with input and output paths and optional context. - constexpr FileSystem(const Str255& inputPath, const Str255& outputPath, void* context = nullptr) noexcept : - m_inputPath(inputPath), m_outputPath(outputPath), m_context(context), - m_recursiveBool(), m_fileType(Type::Camera), m_size(), m_freeSpace(), m_newImageSize(), - m_numberOfFiles(), m_numberOfSnippets(), m_deviceGroupMask(), m_reserved(){} - - /// Input or source file. - constexpr const Str255& inputPath() const noexcept{ - return m_inputPath; - } - - /// Sets input or source file. - void setInputPath(const Str255& path) noexcept{ - m_inputPath = path; - } - - /// Operation result, or destination file. - constexpr const Str255& outputPath() const noexcept{ - return m_outputPath; - } - - /// Sets operation result, or destination file. - void setOutputPath(const Str255& path) noexcept{ - m_outputPath = path; - } - - /// Source specific context. - constexpr void* context() const noexcept{ - return m_context; - } - - /// Sets source specific context. - void setContext(void* context) noexcept{ - m_context = context; - } - - /// Whether the operation is recursive. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::Delete. - constexpr Bool recursive() const noexcept{ - return m_recursiveBool; - } - - /// Sets whether the operation is recursive. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::Delete. - void setRecursive(Bool recursive) noexcept{ - m_recursiveBool = recursive; - } - - /// File type. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - constexpr Type type() const noexcept{ - return m_fileType; - } - - /// Sets file type. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - void setType(Type type) noexcept{ - m_fileType = type; - } - - /// Number of bytes of the entry. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - constexpr UInt32 size() const noexcept{ - return m_size; - } - - /// Sets number of bytes of the entry. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - void setSize(UInt32 size) noexcept{ - m_size = size; - } - - /// Creation date of the file. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - /// YYYY/MM/DD HH:mm:SS:sss - constexpr const Str32& createdTimeDate() const noexcept{ - return m_createdTimeDate; - } - - /// Sets creation date of the file. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - /// YYYY/MM/DD HH:mm:SS:sss - void setCreatedTimeDate(const Str32& val) noexcept{ - m_createdTimeDate = val; - } - - /// Modification date of the file. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - /// YYYY/MM/DD HH:mm:SS:sss - constexpr const Str32& modifiedTimeDate() const noexcept{ - return m_modifiedTimeDate; - } - - /// Sets modification date of the file. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - /// YYYY/MM/DD HH:mm:SS:sss - void setModifiedTimeDate(const Str32& val) noexcept{ - m_modifiedTimeDate = val; - } - - /// Number of bytes left on the device. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - constexpr UInt32 freeSpace() const noexcept{ - return m_freeSpace; - } - - /// Sets number of bytes left on the device. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - void setFreeSpace(UInt32 freeSpace) noexcept{ - m_freeSpace = freeSpace; - } - - /// Estimated image size in bytes. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - constexpr Int32 newImageSize() const noexcept{ - return m_newImageSize; - } - - /// Sets estimated image size in bytes. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - void setNewImageSize(Int32 newImageSize) noexcept{ - m_newImageSize = newImageSize; - } - - /// Total number of files including subdirectories. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - constexpr UInt32 files() const noexcept{ - return m_numberOfFiles; - } - - /// Sets total number of files including subdirectories. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - void setFiles(UInt32 files) noexcept{ - m_numberOfFiles = files; - } - - /// Number of audio snippets. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - constexpr UInt32 snippets() const noexcept{ - return m_numberOfSnippets; - } - - /// Sets number of audio snippets. - /// Valid for Msg::GetInfo, Msg::GetFileFirst and Msg::GetFileNext. - void snippets(UInt32 snippets) noexcept{ - m_numberOfSnippets = snippets; - } - - /// See manual for explanation of this field, `DeviceGroupMask`. - constexpr UInt32 groupMask() const noexcept{ - return m_deviceGroupMask; - } - - /// See manual for explanation of this field, `DeviceGroupMask`. - void groupMask(UInt32 groupMask) noexcept{ - m_deviceGroupMask = groupMask; - } - -private: - void unused() const{ - Detail::unused(m_reserved); - } - - Str255 m_inputPath; - Str255 m_outputPath; - void* m_context; - - // Copy, Delete - union { - int m_recursive; - Bool m_recursiveBool; - }; - - // GetInfo - Type m_fileType; - UInt32 m_size; - Str32 m_createdTimeDate; - Str32 m_modifiedTimeDate; - UInt32 m_freeSpace; - Int32 m_newImageSize; - UInt32 m_numberOfFiles; - UInt32 m_numberOfSnippets; - UInt32 m_deviceGroupMask; - Int8 m_reserved[508]; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_FILESYSTEM_HPP diff --git a/twain/twain/twpp/fix32.hpp b/twain/twain/twpp/fix32.hpp deleted file mode 100644 index fc99b79..0000000 --- a/twain/twain/twpp/fix32.hpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_FIX32_HPP -#define TWPP_DETAIL_FILE_FIX32_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -static constexpr inline Int32 floatToValue(float val){ - return static_cast( - (val >= 0.0f) ? - (val * 65536.0f + 0.5f) : - (val * 65536.0f - 0.5f) - ); -} - -static constexpr inline Int16 floatToWhole(float val){ - return static_cast(floatToValue(val) >> 16); -} - -static constexpr inline UInt16 floatToFrac(float val){ - return static_cast(floatToValue(val) & 0xFFFF); -} - -} - -TWPP_DETAIL_PACK_BEGIN -/// TWAIN fixed point fractional type. -/// The fractional part has resolution of 1/65536. -class Fix32 { - -public: - /// Creates zero-initialized fixed type. - constexpr Fix32() noexcept : - m_whole(0), m_frac(0){} - - /// Creates fixed type from float at compile time if possible. - constexpr Fix32(float value) noexcept : - m_whole(Detail::floatToWhole(value)), m_frac(Detail::floatToFrac(value)){} - - /// Creates fixed type from whole and fractional parts. - /// The fractional part has resolution of 1/65536. - constexpr Fix32(Int16 whole, UInt16 frac) noexcept : - m_whole(whole), m_frac(frac){} - - - /// Whole part of this fixed type. - constexpr Int16 whole() const noexcept{ - return m_whole; - } - - /// Sets whole part of this fixed type. - void setWhole(Int16 whole) noexcept{ - m_whole = whole; - } - - /// Fractional part of this fixed type. - /// Resolution of 1/65536. - constexpr UInt16 frac() const noexcept{ - return m_frac; - } - - /// Sets fractional part of this fixed type. - /// Resolution of 1/65536. - void setFrac(UInt16 frac) noexcept{ - m_frac = frac; - } - - explicit constexpr operator float() const noexcept{ - return m_whole + m_frac / 65536.0f; - } - - constexpr float toFloat() const noexcept{ - return m_whole + m_frac / 65536.0f; - } - - constexpr Fix32 operator-() const noexcept{ - return -toFloat(); - } - -private: - Int16 m_whole; - UInt16 m_frac; - -}; -TWPP_DETAIL_PACK_END - -namespace Detail { - -static inline constexpr Fix32 fix32AddHelper(Int32 frac, Int16 whole){ - return frac < 65536 ? Fix32(whole, frac) : Fix32(whole + 1, frac - 65536); -} - -static inline constexpr Fix32 fix32SubHelper(Int32 frac, Int16 whole){ - return frac >= 0 ? Fix32(whole, frac) : Fix32(whole - 1, frac + 65536); -} - -} - -static inline constexpr bool operator>(Fix32 a, Fix32 b) noexcept{ - return a.whole() > b.whole() || (a.whole() == b.whole() && a.frac() > b.frac()); -} - -static inline constexpr bool operator<(Fix32 a, Fix32 b) noexcept{ - return a.whole() < b.whole() || (a.whole() == b.whole() && a.frac() < b.frac()); -} - -static inline constexpr bool operator>=(Fix32 a, Fix32 b) noexcept{ - return !(a < b); -} - -static inline constexpr bool operator<=(Fix32 a, Fix32 b) noexcept{ - return !(a > b); -} - -static inline constexpr bool operator==(Fix32 a, Fix32 b) noexcept{ - return a.whole() == b.whole() && a.frac() == b.frac(); -} - -static inline constexpr bool operator!=(Fix32 a, Fix32 b) noexcept{ - return !(a == b); -} - -static inline constexpr Fix32 operator+(Fix32 a, Fix32 b) noexcept{ - return Detail::fix32AddHelper(static_cast(a.frac()) + b.frac(), a.whole() + b.whole()); -} - -static inline constexpr Fix32 operator-(Fix32 a, Fix32 b) noexcept{ - return Detail::fix32SubHelper(static_cast(a.frac()) - b.frac(), a.whole() - b.whole()); -} - -static inline constexpr Fix32 operator*(Fix32 a, Fix32 b) noexcept{ - return Fix32(static_cast(a) * static_cast(b)); -} - -static inline constexpr Fix32 operator/(Fix32 a, Fix32 b) noexcept{ // wonder about zero b - return Fix32(static_cast(a) / static_cast(b)); -} - -static inline Fix32& operator+=(Fix32& a, Fix32 b) noexcept{ - return a = a + b; -} - -static inline Fix32& operator-=(Fix32& a, Fix32 b) noexcept{ - return a = a - b; -} - -static inline Fix32& operator*=(Fix32& a, Fix32 b) noexcept{ - return a = a * b; -} - -static inline Fix32& operator/=(Fix32& a, Fix32 b) noexcept{ // wonder about zero b - return a = a / b; -} - -namespace Literals { - -static inline constexpr Fix32 operator "" _fix(long double val) noexcept{ - return Fix32(static_cast(val)); -} - -static inline constexpr Fix32 operator "" _fix(unsigned long long val) noexcept{ - return Fix32(static_cast(val)); -} - -} - -} - -#endif // TWPP_DETAIL_FILE_FIX32_HPP - diff --git a/twain/twain/twpp/frame.hpp b/twain/twain/twpp/frame.hpp deleted file mode 100644 index 7c87816..0000000 --- a/twain/twain/twpp/frame.hpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_FRAME_HPP -#define TWPP_DETAIL_FILE_FRAME_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Section of an image to retrieve. -class Frame { - -public: - /// Creates zero-initialized frame. - constexpr Frame() noexcept{} - - /// Creates frame with set top-left and bottom-right corners. - constexpr Frame(Fix32 left, Fix32 top, Fix32 right, Fix32 bottom) noexcept : - m_left(left), m_top(top), m_right(right), m_bottom(bottom){} - - /// Left position of the image frame. - constexpr Fix32 left() const noexcept{ - return m_left; - } - - /// Sets left position of the image frame. - void setLeft(Fix32 left) noexcept{ - m_left = left; - } - - /// Top position of the image frame. - constexpr Fix32 top() const noexcept{ - return m_top; - } - - /// Sets top position of the image frame. - void setTop(Fix32 top) noexcept{ - m_top = top; - } - - /// Right position of the image frame. - constexpr Fix32 right() const noexcept{ - return m_right; - } - - /// Sets right position of the image frame. - void setRight(Fix32 right) noexcept{ - m_right = right; - } - - /// Bottom position of the image frame. - constexpr Fix32 bottom() const noexcept{ - return m_bottom; - } - - /// Sets bottom position of the image frame. - void setBottom(Fix32 bottom) noexcept{ - m_bottom = bottom; - } - -private: - Fix32 m_left; - Fix32 m_top; - Fix32 m_right; - Fix32 m_bottom; - -}; -TWPP_DETAIL_PACK_END - -static constexpr inline bool operator==(const Frame& a, const Frame& b) noexcept{ - return a.left() == b.left() && a.top() == b.top() && a.right() == b.right() && a.bottom() == b.bottom(); -} - -static constexpr inline bool operator!=(const Frame& a, const Frame& b) noexcept{ - return !(a == b); -} - -} - -#endif // TWPP_DETAIL_FILE_FRAME_HPP - diff --git a/twain/twain/twpp/identity.hpp b/twain/twain/twpp/identity.hpp deleted file mode 100644 index b50e930..0000000 --- a/twain/twain/twpp/identity.hpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2017 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_IDENTITY_HPP -#define TWPP_DETAIL_FILE_IDENTITY_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -static constexpr const UInt32 identV2 = TWPP_DETAIL_IS_DS ? Detail::Ds2 : Detail::App2; - -} - -TWPP_DETAIL_PACK_BEGIN -/// Source or application version information. -class Version { - -public: - /// Creates default-initialized version. - constexpr Version() noexcept : - m_majorNum(0), m_minorNum(0), m_language(Language::English), - m_country(Country::UnitedKingdom){} - - /// Creates version initialized with supplied values. - constexpr Version( - UInt16 majorNumber, - UInt16 minorNumber, - Language language, - Country country, - const Str32& info = Str32()) noexcept : - m_majorNum(majorNumber), m_minorNum(minorNumber), m_language(language), - m_country(country), m_info(info){} - - /// Major version number of the source or application. - constexpr UInt16 majorNumber() const noexcept{ - return m_majorNum; - } - - /// Sets major version number of the source or application. - void setMajorNumber(UInt16 major) noexcept{ - m_majorNum = major; - } - - /// Minor version number of the source or application. - constexpr UInt16 minorNumber() const noexcept{ - return m_minorNum; - } - - /// Sets minor version number of the source or application. - void setMinorNumber(UInt16 minor) noexcept{ - m_minorNum = minor; - } - - /// Language of the source or application. - constexpr Language language() const noexcept{ - return m_language; - } - - /// Sets language of the source or application. - void setLanguage(Language language) noexcept{ - m_language = language; - } - - /// Original country of the source or application. - constexpr Country country() const noexcept{ - return m_country; - } - - /// Set original country of the source or application. - void setCountry(Country country) noexcept{ - m_country = country; - } - - /// Additional version information of the source or application. - constexpr const Str32& info() const noexcept{ - return m_info; - } - - /// Sets additional version information of the source or application. - void setInfo(const Str32& info) noexcept{ - m_info = info; - } - -private: - UInt16 m_majorNum; - UInt16 m_minorNum; - Language m_language; - Country m_country; - Str32 m_info; - -}; - -/// Source or application identity. -/// Uniquely identifies an endpoint. -class Identity { - -public: - typedef -#if defined(TWPP_DETAIL_OS_MAC) - void* -#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) - UInt32 -#else -# error "Identity::Id for your platform here" -#endif - Id; - - /// Creates default-initialized identity. - /// ID is set to zero. - /// TWAIN protocol is always Detail::ProtoMajor and Detail::ProtoMinor. - /// Supported group always contains DG::Control and V2. - constexpr Identity() noexcept : - m_id(), m_protoMaj(Detail::ProtoMajor), m_protoMin(Detail::ProtoMinor), - m_groups(DataGroup::Control | Detail::identV2){} - - /// Creates identity initialized with supplied values. - /// ID is set to zero. - /// TWAIN protocol is always Detail::ProtoMajor and Detail::ProtoMinor. - /// Supported group always contains DG::Control and V2. - constexpr Identity( - const Version& version, - DataGroup group, - const Str32& manufacturer, - const Str32& productFamily, - const Str32& productName) noexcept : - m_id(), m_version(version), m_protoMaj(Detail::ProtoMajor), - m_protoMin(Detail::ProtoMinor), m_groups(DataGroup::Control | group | Detail::identV2), - m_manuf(manufacturer), m_prodFamily(productFamily), m_prodName(productName){} - - /// Creates identity initialized with supplied values. - constexpr Identity( - Id id, - const Version& version, - UInt16 protoMajor, - UInt16 protoMinor, - UInt32 groups, - const Str32& manufacturer, - const Str32& productFamily, - const Str32& productName) noexcept : - m_id(id), m_version(version), m_protoMaj(protoMajor), m_protoMin(protoMinor), - m_groups(groups), m_manuf(manufacturer), m_prodFamily(productFamily), - m_prodName(productName){} - - /// DSM-supplied ID of this identity. - constexpr Id id() const{ - return m_id; - } - - /// Version information. - constexpr const Version& version() const noexcept{ - return m_version; - } - - /// Whether a data group is supported. - constexpr bool supports(DataGroup group) const noexcept{ - return (m_groups & group) != 0; - } - - /// Whether this is V2 application. - constexpr bool isAppV2() const noexcept{ - return (m_groups & Detail::App2) != 0; - } - - /// Whether this is V2 DSM. - constexpr bool isDsmV2() const noexcept{ - return (m_groups & Detail::Dsm2) != 0; - } - - /// Whether this is V2 source. - constexpr bool isDsV2() const noexcept{ - return (m_groups & Detail::Ds2) != 0; - } - - /// The manufacturer. - /// Manufacturer and product name uniquely identify a source. - constexpr const Str32& manufacturer() const noexcept{ - return m_manuf; - } - - /// The product name. - /// Manufacturer and product name uniquely identify a source. - constexpr const Str32& productName() const noexcept{ - return m_prodName; - } - - /// The product family. - constexpr const Str32& productFamily() const noexcept{ - return m_prodFamily; - } - - /// Raw data group flags. - constexpr UInt32 dataGroupsRaw() const noexcept{ - return m_groups; - } - - /// TWAIN protocol major version. - constexpr UInt16 protocolMajor() const noexcept{ - return m_protoMaj; - } - - /// TWAIN protocol minor version. - constexpr UInt16 protocolMinor() const noexcept{ - return m_protoMin; - } - -private: - Id m_id; - Version m_version; - UInt16 m_protoMaj; - UInt16 m_protoMin; - UInt32 m_groups; - Str32 m_manuf; - Str32 m_prodFamily; - Str32 m_prodName; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_IDENTITY_HPP diff --git a/twain/twain/twpp/imageinfo.hpp b/twain/twain/twpp/imageinfo.hpp deleted file mode 100644 index 78cbf84..0000000 --- a/twain/twain/twpp/imageinfo.hpp +++ /dev/null @@ -1,190 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_IMAGEINFO_HPP -#define TWPP_DETAIL_FILE_IMAGEINFO_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Contains information about transfered image. -class ImageInfo { - - typedef Detail::FixedArray BitsPerSampleImpl; - -public: - typedef Int16 BitsPerSample[8]; - - /// Creates zero-initialized info. - constexpr ImageInfo() noexcept : - m_imgWidth(0), m_imgHeight(0), m_spp(0), m_bps(), m_bpp(0), - m_planar(0), m_pixelType(PixelType::BlackWhite), m_compression(Compression::None){} - - /// Creates info with supplied values. - template - constexpr ImageInfo( - Fix32 xResolution, - Fix32 yResolution, - Int32 width, - Int32 height, - Int16 samplesPerPixel, - const Int16(& bitsPerSample)[inputSize], - Int16 bitsPerPixel, - Bool planar, - PixelType pixelType, - Compression compression - ) noexcept : - m_xres(xResolution), m_yres(yResolution), m_imgWidth(width), m_imgHeight(height), - m_spp(samplesPerPixel), m_bps(bitsPerSample), m_bpp(bitsPerPixel), m_planar(planar), - m_pixelType(pixelType), m_compression(compression){} - - /// X-axis resolution of the image. - constexpr Fix32 xResolution() const noexcept{ - return m_xres; - } - - /// Sets x-axis resolution of the image. - void setXResolution(Fix32 xres) noexcept{ - m_xres = xres; - } - - /// Y-axis resolution of the image. - constexpr Fix32 yResolution() const noexcept{ - return m_yres; - } - - /// Sets y-axis resolution of the image. - void setYResolution(Fix32 yres) noexcept{ - m_yres = yres; - } - - /// Image width in pixels. - constexpr Int32 width() const noexcept{ - return m_imgWidth; - } - - /// Sets image width in pixels. - void setWidth(Int32 width) noexcept{ - m_imgWidth = width; - } - - /// Image height in pixels. - constexpr Int32 height() const noexcept{ - return m_imgHeight; - } - - /// Sets image height in pixels. - void setHeight(Int32 height) noexcept{ - m_imgHeight = height; - } - - /// Samples per single pixel. - constexpr Int16 samplesPerPixel() const noexcept{ - return m_spp; - } - - /// Sets samples per single pixel. - void setSamplesPerPixel(Int16 spp) noexcept{ - m_spp = spp; - } - - /// Array of bits per sample. - /// Contains `samplesPerPixel` entries. - constexpr const BitsPerSample& bitsPerSample() const noexcept{ - return m_bps.array(); - } - - /// Array of bits per sample. - /// Contains `samplesPerPixel` entries. - BitsPerSample& bitsPerSample() noexcept{ - return m_bps.array(); - } - - /// Total number of bits per pixel. - /// This should be true: bitsPerPixel = SUM[i=0..samplesPerPixel-1](bitsPerSample[i]) - constexpr Int16 bitsPerPixel() const noexcept{ - return m_bpp; - } - - /// Sets total number of bits per pixel. - /// This should be true: bitsPerPixel = SUM[i=0..samplesPerPixel-1](bitsPerSample[i]) - void setBitsPerPixel(Int16 bpp) noexcept{ - m_bpp = bpp; - } - - /// Whether the image is planar (consists of several sample planes) or is chunky - /// (samples are transferes in one plane and are interlaced). - constexpr Bool planar() const noexcept{ - return m_planar; - } - - /// Sets whether the image is planar (consists of several sample planes) or is chunky - /// (samples are transferes in one plane and are interlaced). - void setPlanar(Bool planar) noexcept{ - m_planar = planar; - } - - /// The type of image. - constexpr PixelType pixelType() const noexcept{ - return m_pixelType; - } - - /// Sets the type of image. - void setPixelType(PixelType pixelType) noexcept{ - m_pixelType = pixelType; - } - - /// Image compression. - constexpr Compression compression() const noexcept{ - return m_compression; - } - - /// Sets image compression. - void compression(Compression compression) noexcept{ - m_compression = compression; - } - -private: - Fix32 m_xres; - Fix32 m_yres; - Int32 m_imgWidth; - Int32 m_imgHeight; - Int16 m_spp; - BitsPerSampleImpl m_bps; - Int16 m_bpp; - Bool m_planar; - PixelType m_pixelType; - Compression m_compression; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_IMAGEINFO_HPP - diff --git a/twain/twain/twpp/imagelayout.hpp b/twain/twain/twpp/imagelayout.hpp deleted file mode 100644 index c61eb5b..0000000 --- a/twain/twain/twpp/imagelayout.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_IMAGELAYOUT_HPP -#define TWPP_DETAIL_FILE_IMAGELAYOUT_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Provides image size and its position on the scanner and information about order of the image. -class ImageLayout { - -public: - /// Creates layout. - constexpr ImageLayout( - const Frame& frame = Frame(), - UInt32 documentNumber = 1, - UInt32 pageNumber = 1, - UInt32 frameNumber = 1 - ) noexcept : - m_frame(frame), m_docNumber(documentNumber), - m_pageNumber(pageNumber), m_frameNumber(frameNumber){} - - /// The image frame. - constexpr const Frame& frame() const noexcept{ - return m_frame; - } - - /// Sets the image frame. - void setFrame(const Frame& frame) noexcept{ - m_frame = frame; - } - - /// Number of the document, set by source. - constexpr UInt32 documentNumber() const noexcept{ - return m_docNumber; - } - - /// Sets number of the document. - void setDocumentNumber(UInt32 documentNumber) noexcept{ - m_docNumber = documentNumber; - } - - /// Number of the page, set by source. - constexpr UInt32 pageNumber() const noexcept{ - return m_pageNumber; - } - - /// Sets number of the page. - void setPageNumber(UInt32 pageNumber) noexcept{ - m_pageNumber = pageNumber; - } - - /// Number of the frame, set by source. - constexpr UInt32 frameNumber() const noexcept{ - return m_frameNumber; - } - - /// Sets number of the frame. - void setFrameNumber(UInt32 frameNumber) noexcept{ - m_frameNumber = frameNumber; - } - -private: - Frame m_frame; - UInt32 m_docNumber; - UInt32 m_pageNumber; - UInt32 m_frameNumber; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_IMAGELAYOUT_HPP diff --git a/twain/twain/twpp/imagememxfer.hpp b/twain/twain/twpp/imagememxfer.hpp deleted file mode 100644 index 2be7a3a..0000000 --- a/twain/twain/twpp/imagememxfer.hpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_IMAGEMEMXFER_HPP -#define TWPP_DETAIL_FILE_IMAGEMEMXFER_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -namespace Detail { - -/// Structure holding the information and data of memory and memory file transfers. -class ImageMemXferImpl { - -public: - /// Creates a zero-initialized structure without any memory. - ImageMemXferImpl() noexcept : - m_compression(Compression::None), m_bytesPerRow(0), m_columns(0), m_rows(0), - m_xoff(0), m_yoff(0), m_bytesWritten(0){} - - /// Creates an initialized structure from the supplied values and memory. - /// The ownership of the memory is taken over. - ImageMemXferImpl( - Compression compression, - UInt32 bytesPerRow, - UInt32 columns, - UInt32 rows, - UInt32 xOffset, - UInt32 yOffset, - UInt32 bytesWritten, - Memory memory - ) noexcept : - m_compression(compression), m_bytesPerRow(bytesPerRow), - m_columns(columns), m_rows(rows), m_xoff(xOffset), m_yoff(yOffset), - m_bytesWritten(bytesWritten), m_memory(std::move(memory)){} - - /// Compression used in the transfer. - Compression compression() const noexcept{ - return m_compression; - } - - /// Sets compression used in the transfer. - void setCompression(Compression compression) noexcept{ - m_compression = compression; - } - - /// Number of bytes per single row. - UInt32 bytesPerRow() const noexcept{ - return m_bytesPerRow; - } - - /// Sets number of bytes per single row. - void setBytesPerRow(UInt32 bytesPerRow) noexcept{ - m_bytesPerRow = bytesPerRow; - } - - /// Number of columns in the transfer. - UInt32 columns() const noexcept{ - return m_columns; - } - - /// Sets number of columns in the transfer. - void setColumns(UInt32 columns) noexcept{ - m_columns = columns; - } - - /// Number of rows in the transfer. - UInt32 rows() const noexcept{ - return m_rows; - } - - /// Sets number of rows in the transfer. - void setRows(UInt32 rows) noexcept{ - m_rows = rows; - } - - /// X offset from top-left corner in pixels of the image data in the transfer. - UInt32 xOffset() const noexcept{ - return m_xoff; - } - - /// Sets X offset from top-left corner in pixels of the image data in the transfer. - void setXOffset(UInt32 xOffset) noexcept{ - m_xoff = xOffset; - } - - /// Y offset from top-left corner in pixels of the image data in the transfer. - UInt32 yOffset() const noexcept{ - return m_yoff; - } - - /// Sets Y offset from top-left corner in pixels of the image data in the transfer. - void setYOffset(UInt32 yOffset) noexcept{ - m_yoff = yOffset; - } - - /// Number of bytes in this transfer, always contains whole rows or tiles. - UInt32 bytesWritten() const noexcept{ - return m_bytesWritten; - } - - /// Sets number of bytes in this transfer. - void setBytesWritten(UInt32 bytesWritten) noexcept{ - m_bytesWritten = bytesWritten; - } - - /// Contained memory structure. - const Memory& memory() const noexcept{ - return m_memory; - } - - /// Contained memory structure. - Memory& memory() noexcept{ - return m_memory; - } - -private: - Compression m_compression; - UInt32 m_bytesPerRow; - UInt32 m_columns; - UInt32 m_rows; - UInt32 m_xoff; - UInt32 m_yoff; - UInt32 m_bytesWritten; - Memory m_memory; - -}; - -} - -/// Structure holding the information and data of memory transfer. -class ImageMemXfer : public Detail::ImageMemXferImpl { - -public: - /// Creates a zero-initialized structure without any memory. - ImageMemXfer() noexcept : Detail::ImageMemXferImpl(){} - - /// Creates an initialized structure from the supplied values and memory. - /// The ownership of the memory is taken over. - ImageMemXfer( - Compression compression, - UInt32 bytesPerRow, - UInt32 columns, - UInt32 rows, - UInt32 xOffset, - UInt32 yOffset, - UInt32 bytesWritten, - Memory memory - ) noexcept : Detail::ImageMemXferImpl( - compression, bytesPerRow, columns, rows, xOffset, - yOffset, bytesWritten, std::move(memory)){} - -}; - -/// Structure holding the information and data of memory file transfer. -class ImageMemFileXfer : public Detail::ImageMemXferImpl { - -public: - /// Creates a zero-initialized structure without any memory. - ImageMemFileXfer() noexcept : Detail::ImageMemXferImpl(){} - - /// Creates an initialized structure from the supplied values and memory. - /// The ownership of the memory is taken over. - ImageMemFileXfer( - Compression compression, - UInt32 bytesPerRow, - UInt32 columns, - UInt32 rows, - UInt32 xOffset, - UInt32 yOffset, - UInt32 bytesWritten, - Memory memory - ) noexcept : Detail::ImageMemXferImpl( - compression, bytesPerRow, columns, rows, xOffset, - yOffset, bytesWritten, std::move(memory)){} - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_IMAGEMEMXFER_HPP diff --git a/twain/twain/twpp/imagenativexfer.hpp b/twain/twain/twpp/imagenativexfer.hpp deleted file mode 100644 index 8a90bc0..0000000 --- a/twain/twain/twpp/imagenativexfer.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_IMAGENATIVEXFER_HPP -#define TWPP_DETAIL_FILE_IMAGENATIVEXFER_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Structure holding native transfer image handle. -class ImageNativeXfer { - -public: - template - using Data = Detail::Lock::type>; - - template - using ConstData = Detail::Lock::type>; - - - /// Creates empty, invalid native transfer. - ImageNativeXfer() noexcept : - m_handle(){} - - /// Creates a new ImageNativeXfer object from a handle. - /// The ownership of the handle is taken over. - explicit ImageNativeXfer(Handle h) : - m_handle(h){} - - /// Creates uninitialized native image with defines size in bytes. - /// \throw std::bad_alloc - explicit ImageNativeXfer(UInt32 size) : - m_handle(Detail::alloc(size)){} - - /// Data of this native transfer. - /// Actual type depends on system and source. - /// Windows sources use BMP format without file header, version varies. - /// Linux uses TIFF, version varies. - /// Mac uses QuickDraw Picture. - template - Data data() noexcept{ - return m_handle.lock::type>(); - } - - /// Data of this native transfer. - /// Actual type depends on system and source. - /// Windows sources use BMP format without file header, version varies. - /// Linux uses TIFF, version varies. - /// Mac uses QuickDraw Picture. - template - ConstData data() const noexcept{ - return m_handle.lock::type>(); - } - - operator bool() const noexcept{ - return m_handle; - } - - /// Releases the contained handle, making user responsible for freeing it. - Handle release() noexcept{ - return m_handle.release(); - } - -private: - Detail::UniqueHandle m_handle; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_IMAGENATIVEXFER_HPP - diff --git a/twain/twain/twpp/internal.hpp b/twain/twain/twpp/internal.hpp deleted file mode 100644 index 8abe360..0000000 --- a/twain/twain/twpp/internal.hpp +++ /dev/null @@ -1,158 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2017 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_INTERNAL_HPP -#define TWPP_DETAIL_FILE_INTERNAL_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -struct AudioFileXfer {}; -struct ImageFileXfer {}; -typedef Memory IccProfileMemory; - -namespace Detail { - -typedef ReturnCode (TWPP_DETAIL_CALLSTYLE* DsmEntry)( - Identity* origin, - Identity* dest, - DataGroup dg, - Dat dat, - Msg msg, - void* data -); - -typedef DsmEntry CallBackFunc; - -typedef -#if defined(TWPP_DETAIL_OS_MAC) -void* -#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) -UInt32 -#else -# error "CallBackConstant for your platform here" -#endif -CallBackConstant; - - -TWPP_DETAIL_PACK_BEGIN -struct EntryPoint { - constexpr EntryPoint() noexcept : - m_size(sizeof(EntryPoint)), m_entry(nullptr), m_alloc(nullptr), - m_free(nullptr), m_lock(nullptr), m_unlock(nullptr){} - - UInt32 m_size; - DsmEntry m_entry; - MemAlloc m_alloc; - MemFree m_free; - MemLock m_lock; - MemUnlock m_unlock; -}; - -struct CallBack { - - constexpr CallBack(CallBackFunc func, CallBackConstant constant, Msg msg) noexcept : - m_func(func), m_constant(constant), m_msg(msg){} - - CallBackFunc m_func; - CallBackConstant m_constant; - Msg m_msg; - -}; - -struct CallBack2 { - - constexpr CallBack2(CallBackFunc func, UIntPtr constant, Msg msg) noexcept : - m_func(func), m_constant(constant), m_msg(msg){} - - CallBackFunc m_func; - UIntPtr m_constant; - Msg m_msg; -}; -TWPP_DETAIL_PACK_END - -/// Manages DSM dll/so/framework connection. -class DsmLib { - -public: - constexpr DsmLib() noexcept : - m_handle(DsmLibOs::nullHandle){} - - ~DsmLib(){ - unload(); - } - - DsmLib(const DsmLib&) = delete; - DsmLib& operator=(const DsmLib&) = delete; - - DsmLib(DsmLib&& o) noexcept : - m_handle(o.m_handle){ - - o.m_handle = DsmLibOs::nullHandle; - } - - DsmLib& operator=(DsmLib&& o) noexcept{ - if (&o != this){ - unload(); - - m_handle = o.m_handle; - o.m_handle = DsmLibOs::nullHandle; - } - - return *this; - } - - operator bool() const noexcept{ - return m_handle != DsmLibOs::nullHandle; - } - - bool load(bool preferOld = false) noexcept{ - m_handle = DsmLibOs::load(preferOld); - return m_handle != DsmLibOs::nullHandle; - } - - void unload() noexcept{ - if (m_handle != DsmLibOs::nullHandle){ - DsmLibOs::unload(m_handle); - m_handle = DsmLibOs::nullHandle; - } - } - - DsmEntry resolve() const noexcept{ - return DsmLibOs::resolve(m_handle); - } - -private: - DsmLibOs::Handle m_handle; - -}; - -} - -} - -#endif // TWPP_DETAIL_FILE_INTERNAL_HPP diff --git a/twain/twain/twpp/jpegcompression.hpp b/twain/twain/twpp/jpegcompression.hpp deleted file mode 100644 index b42a176..0000000 --- a/twain/twain/twpp/jpegcompression.hpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_JPEGCOMPRESSION_HPP -#define TWPP_DETAIL_FILE_JPEGCOMPRESSION_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// See manual for more info. -class JpegCompression { - -public: - typedef UInt16 UInt16Arr4[4]; - typedef Memory MemoryArr2[2]; - typedef Memory MemoryArr4[4]; - - JpegCompression() noexcept : - m_colorSpace(PixelType::BlackWhite), m_subSampling(0x10001000), m_components(0), - m_restartFrequency(0), m_quantMap(), m_huffmanMap(){} - - template< - std::size_t quantTableMapSize, - std::size_t quantTableSize, - std::size_t huffmanTableMapSize, - std::size_t huffmanDcSize, - std::size_t huffmanAcSize - > - JpegCompression( - PixelType colorSpace, - UInt32 subSampling, - UInt16 components, - UInt16 restartFrequency, - const UInt16(& quantTableMap)[quantTableMapSize], - Memory(& quantTable)[quantTableSize], - const UInt16(& huffmanTableMap)[huffmanTableMapSize], - Memory(& huffmanDc)[huffmanDcSize], - Memory(& huffmanAc)[huffmanAcSize] - ) noexcept : - m_colorSpace(colorSpace), - m_subSampling(subSampling), - m_components(components), - m_restartFrequency(restartFrequency), - m_quantMap(quantTableMap), - m_huffmanMap(huffmanTableMap){ - - for (std::size_t i = 0; i < quantTableSize; i++){ - m_quantTable[i] = std::move(quantTable[i]); - } - - for (std::size_t i = 0; i < huffmanDcSize; i++){ - m_huffmanDc[i] = std::move(huffmanDc[i]); - } - - for (std::size_t i = 0; i < huffmanAcSize; i++){ - m_huffmanAc[i] = std::move(huffmanAc[i]); - } - } - - PixelType pixelType() const noexcept{ - return m_colorSpace; - } - - void setPixelType(PixelType pixelType) noexcept{ - m_colorSpace = pixelType; - } - - UInt32 subSampling() const noexcept{ - return m_subSampling; - } - - void setSubSampling(UInt32 subSampling) noexcept{ - m_subSampling = subSampling; - } - - UInt16 components() const noexcept{ - return m_components; - } - - void setComponents(UInt16 components) noexcept{ - m_components = components; - } - - UInt16 restartFrequency() const noexcept{ - return m_restartFrequency; - } - - void setRestartFrequency(UInt16 restartFrequency) noexcept{ - m_restartFrequency = restartFrequency; - } - - const UInt16Arr4& quantTableMap() const noexcept{ - return m_quantMap.array(); - } - - UInt16Arr4& quantTableMap() noexcept{ - return m_quantMap.array(); - } - - const MemoryArr4& quantTable() const noexcept{ - return m_quantTable; - } - - MemoryArr4& quantTable() noexcept{ - return m_quantTable; - } - - const UInt16Arr4& huffmanTableMap() const noexcept{ - return m_huffmanMap.array(); - } - - UInt16Arr4& huffmanTableMap() noexcept{ - return m_huffmanMap.array(); - } - - const MemoryArr2& huffmanDc() const noexcept{ - return m_huffmanDc; - } - - MemoryArr2& huffmanDc() noexcept{ - return m_huffmanDc; - } - - const MemoryArr2& huffmanAc() const noexcept{ - return m_huffmanAc; - } - - MemoryArr2& huffmanAc() noexcept{ - return m_huffmanAc; - } - -private: - PixelType m_colorSpace; - UInt32 m_subSampling; - UInt16 m_components; - UInt16 m_restartFrequency; - Detail::FixedArray m_quantMap; - MemoryArr4 m_quantTable; - Detail::FixedArray m_huffmanMap; - MemoryArr2 m_huffmanDc; - MemoryArr2 m_huffmanAc; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_JPEGCOMPRESSION_HPP diff --git a/twain/twain/twpp/memory.hpp b/twain/twain/twpp/memory.hpp deleted file mode 100644 index 63859b1..0000000 --- a/twain/twain/twpp/memory.hpp +++ /dev/null @@ -1,194 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_MEMORY_HPP -#define TWPP_DETAIL_FILE_MEMORY_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -namespace Flags { - -enum { - AppOwns = 0x0001, - DsmOwns = 0x0002, - DsOwns = 0x0004, - Pointer = 0x0008, - Handle = 0x0010 -}; - - -#if !defined(TWPP_IS_DS) -static constexpr const UInt32 thisOwns = AppOwns; -static constexpr const UInt32 otherOwns = DsOwns; -#else -static constexpr const UInt32 thisOwns = DsOwns; -static constexpr const UInt32 otherOwns = AppOwns; -#endif - -} - -} - -TWPP_DETAIL_PACK_BEGIN -/// Holds and potentially owns a block of memory using either pointer or handle. -class Memory { - -public: - typedef Detail::MaybeLock Data; - typedef Detail::MaybeLock ConstData; - - /// Creates an empty memory. - constexpr Memory() noexcept : - m_flags(0), m_size(0), m_data(nullptr){} - - /// Creates a memory block of supplied size. - /// \throw std::bad_alloc - explicit Memory(UInt32 size) : - m_flags(Detail::Flags::thisOwns | Detail::Flags::Handle), m_size(size), - m_data(Detail::alloc(size).raw()){} - - /// Creates a new memory object from Handle. - /// The memory ownership is taken over. - /// \param h The handle, see thisOwns for more information about memory ownership. - /// \param size Size of the memory in bytes, that handle h manages. - /// \param thisOwns { - /// If true, this object frees the memory once it goes out of scope. - /// - /// If false the memory is not freed, and MUST be passed to the other side - /// (APP->DS or DS->APP) of the connection, that will free it. - /// } - Memory(Handle h, UInt32 size, bool thisOwns = true) noexcept : - m_flags((thisOwns ? Detail::Flags::thisOwns : Detail::Flags::otherOwns) | Detail::Flags::Handle), - m_size(size), - m_data(h.raw()){} - - /// Creates a memory object from container. - /// The memory object does NOT take over the ownership of the data. - /// Make sure the container is destroyed after the memory object is. - template - explicit Memory(const Container& container) noexcept : - m_flags(Detail::Flags::thisOwns | Detail::Flags::Pointer), - m_size(sizeof(Container::value_type) * container.size()), - m_data(container.data()){} - - /// Creates a memory object from pointer. - /// The memory object does NOT take over the ownership of the data. - /// Make sure the data is destroyed after the memory object is. - constexpr Memory(void* data, UInt32 size) noexcept : - m_flags(Detail::Flags::thisOwns | Detail::Flags::Pointer), m_size(size), - m_data(data){} - - ~Memory(){ - freePriv(); - } - - Memory(const Memory& o) = delete; - Memory& operator=(const Memory& o) = delete; - - Memory(Memory&& o) noexcept : - m_flags(o.m_flags), m_size(o.m_size), m_data(o.m_data) - { - o.m_flags = 0; - o.m_size = 0; - o.m_data = nullptr; - } - - Memory& operator=(Memory&& o) noexcept{ - if (&o != this){ - freePriv(); - - m_flags = o.m_flags; - m_size = o.m_size; - m_data = o.m_data; - - o.m_flags = 0; - o.m_size = 0; - o.m_data = nullptr; - } - - return *this; - } - - /// The data in this memory block. - ConstData data() const noexcept{ - return m_flags & Detail::Flags::Handle ? - ConstData(Handle(static_cast(m_data))) : - ConstData(static_cast(m_data)); - } - - /// The data in this memory block. - Data data() noexcept{ - return m_flags & Detail::Flags::Handle ? - Data(Handle(static_cast(m_data))) : - Data(static_cast(m_data)); - } - - /// Number of bytes in the memory block. - UInt32 size() const noexcept{ - return m_size; - } - - /// In case of handle, frees memory regardless its owner; does nothing otherwise (pointer). - /// Potentially unsafe operation. - void free(){ - if (m_flags & Detail::Flags::Handle){ - Handle h(static_cast(m_data)); - if (h){ - Detail::free(h); - } - - m_size = 0; - m_data = nullptr; - m_flags = 0; - } - } - -private: - void freePriv(){ - if (m_flags & Detail::Flags::thisOwns){ - if (m_flags & Detail::Flags::Handle){ - Detail::free(Handle(static_cast(m_data))); - } - } - } - - UInt32 m_flags; - UInt32 m_size; - void* m_data; - -}; -TWPP_DETAIL_PACK_END - - - -} - -#endif // TWPP_DETAIL_FILE_MEMORY_HPP - diff --git a/twain/twain/twpp/memoryops.hpp b/twain/twain/twpp/memoryops.hpp deleted file mode 100644 index abf499a..0000000 --- a/twain/twain/twpp/memoryops.hpp +++ /dev/null @@ -1,439 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2017 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_MEMORYOPS_HPP -#define TWPP_DETAIL_FILE_MEMORYOPS_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -extern "C" { - -typedef Handle::Raw (TWPP_DETAIL_CALLSTYLE* MemAlloc)(UInt32 size); -typedef void (TWPP_DETAIL_CALLSTYLE* MemFree)(Handle::Raw handle); -typedef void* (TWPP_DETAIL_CALLSTYLE* MemLock)(Handle::Raw handle); -typedef void (TWPP_DETAIL_CALLSTYLE* MemUnlock)(Handle::Raw handle); - -} - -// templates behave as if they were defined in at most one module -// ideal for storing static data -template -struct GlobalMemFuncs { - -#if defined(TWPP_DETAIL_OS_WIN) - static Handle::Raw TWPP_DETAIL_CALLSTYLE defAlloc(UInt32 size){ - return ::GlobalAlloc(GHND, size); - } - - static void TWPP_DETAIL_CALLSTYLE defFree(Handle::Raw handle){ - ::GlobalFree(handle); - } - - static void* TWPP_DETAIL_CALLSTYLE defLock(Handle::Raw handle){ - return ::GlobalLock(handle); - } - - static void TWPP_DETAIL_CALLSTYLE defUnlock(Handle::Raw handle){ - ::GlobalUnlock(handle); - } -#elif defined(TWPP_DETAIL_OS_MAC) - static Handle::Raw TWPP_DETAIL_CALLSTYLE defAlloc(UInt32 size){ - return ::NewHandle(size); - } - - static void TWPP_DETAIL_CALLSTYLE defFree(Handle::Raw handle){ - ::DisposeHandle(handle); - } - - static void* TWPP_DETAIL_CALLSTYLE defLock(Handle::Raw handle){ - return *handle; - } - - static void TWPP_DETAIL_CALLSTYLE defUnlock(Handle::Raw){ - // noop - } -#elif !defined(TWPP_DETAIL_OS_LINUX) // Linux doesnt need default functions -# error "default memory functions for your platform here" -#endif - - static MemAlloc alloc; - static MemFree free; - static MemLock lock; - static MemUnlock unlock; - -#if defined(TWPP_IS_DS) - static Handle doNotFreeHandle; -#endif - -}; - -#if defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_MAC) -template -MemAlloc GlobalMemFuncs::alloc = GlobalMemFuncs::defAlloc; - -template -MemFree GlobalMemFuncs::free = GlobalMemFuncs::defFree; - -template -MemLock GlobalMemFuncs::lock = GlobalMemFuncs::defLock; - -template -MemUnlock GlobalMemFuncs::unlock = GlobalMemFuncs::defUnlock; -#elif defined(TWPP_DETAIL_OS_LINUX) -template -MemAlloc GlobalMemFuncs::alloc = nullptr; - -template -MemFree GlobalMemFuncs::free = nullptr; - -template -MemLock GlobalMemFuncs::lock = nullptr; - -template -MemUnlock GlobalMemFuncs::unlock = nullptr; -#else -# error "default memory functions setup for your platform here" -#endif - -#if defined(TWPP_IS_DS) - template - Handle GlobalMemFuncs::doNotFreeHandle; -#endif - -inline static void setMemFuncs(MemAlloc alloc, MemFree free, MemLock lock, MemUnlock unlock) noexcept{ - GlobalMemFuncs::alloc = alloc; - GlobalMemFuncs::free = free; - GlobalMemFuncs::lock = lock; - GlobalMemFuncs::unlock = unlock; -} - -inline static void resetMemFuncs() noexcept{ -#if defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_MAC) - GlobalMemFuncs::alloc = GlobalMemFuncs::defAlloc; - GlobalMemFuncs::free = GlobalMemFuncs::defFree; - GlobalMemFuncs::lock = GlobalMemFuncs::defLock; - GlobalMemFuncs::unlock = GlobalMemFuncs::defUnlock; -#elif defined(TWPP_DETAIL_OS_LINUX) - GlobalMemFuncs::alloc = nullptr; - GlobalMemFuncs::free = nullptr; - GlobalMemFuncs::lock = nullptr; - GlobalMemFuncs::unlock = nullptr; -#else -# error "resetMemFuncs for your platform here" -#endif -} - -inline static Handle alloc(UInt32 size){ - auto h = GlobalMemFuncs::alloc(size); - if (!h){ - throw std::bad_alloc(); - } - - return Handle(h); -} - -inline static void* lock(Handle handle) noexcept{ - return GlobalMemFuncs::lock(handle.raw()); -} - -inline static void unlock(Handle handle) noexcept{ - GlobalMemFuncs::unlock(handle.raw()); -} - -inline static void free(Handle handle) noexcept{ - GlobalMemFuncs::free(handle.raw()); -} - -template -static inline T* typeLock(Handle handle) noexcept{ - return static_cast(lock(handle)); -} - -/// A lock that can contain either handle or raw pointer. -/// Locks and unlocks handle, noop for pointer. -template -class MaybeLock { - -public: - constexpr MaybeLock() noexcept : - m_handle(), m_pointer(nullptr){} - - MaybeLock(Handle h) noexcept : - m_handle(h), m_pointer(typeLock(h)){} - - constexpr MaybeLock(T* ptr) noexcept : - m_handle(), m_pointer(ptr){} - - ~MaybeLock(){ - unlock(); - } - - MaybeLock(const MaybeLock& o) noexcept : - m_handle(o.m_handle), m_pointer(o.m_handle ? typeLock(o.m_handle) : o.m_pointer){} - - MaybeLock& operator=(const MaybeLock& o) noexcept{ - if (&o != this){ - unlock(); - - m_handle = o.m_handle; - m_pointer = m_handle ? typeLock(m_handle) : o.m_pointer; - } - - return *this; - } - - - MaybeLock(MaybeLock&& o) noexcept : - m_handle(o.m_handle), m_pointer(o.m_pointer){ - - o.m_handle = Handle(); - o.m_pointer = nullptr; - } - - MaybeLock& operator=(MaybeLock&& o) noexcept{ - if (&o != this){ - unlock(); - - m_handle = o.m_handle; - m_pointer = o.m_pointer; - - o.m_handle = Handle(); - o.m_pointer = nullptr; - } - - return *this; - } - - T* data() const noexcept{ - return m_pointer; - } - - operator T*() const noexcept{ - return m_pointer; - } - - T* operator->() noexcept{ - return m_pointer; - } - - T* operator->() const noexcept{ - return m_pointer; - } - - bool hasData() const noexcept{ - return m_pointer; - } - - operator bool() const noexcept{ - return m_pointer; - } - -private: - void unlock() noexcept{ - if (m_handle){ - Detail::unlock(m_handle); - } - } - - Handle m_handle; - T* m_pointer; - -}; - -/// Simple handle lock. -/// Locks on creation and unlocks on destruction. -template -class Lock { - -public: - constexpr Lock() noexcept : - m_handle(), m_pointer(nullptr){} - - Lock(Handle h) noexcept : - m_handle(h), m_pointer(typeLock(h)){} - - ~Lock(){ - unlock(); - } - - - Lock(const Lock& o) noexcept : - m_handle(o.m_handle), m_pointer(typeLock(o.m_handle)){} - - Lock& operator=(const Lock& o) noexcept{ - if (&o != this){ - unlock(); - - m_handle = o.m_handle; - m_pointer = typeLock(m_handle); - } - - return *this; - } - - - Lock(Lock&& o) noexcept : - m_handle(o.m_handle), m_pointer(o.m_pointer){ - - o.m_handle = Handle(); - o.m_pointer = nullptr; - } - - Lock& operator=(Lock&& o) noexcept{ - if (&o != this){ - unlock(); - - m_handle = o.m_handle; - m_pointer = o.m_pointer; - - o.m_handle = Handle(); - o.m_pointer = nullptr; - } - - return *this; - } - - - T* data() const noexcept{ - return m_pointer; - } - - operator T*() const noexcept{ - return m_pointer; - } - - T* operator->() noexcept{ - return m_pointer; - } - - T* operator->() const noexcept{ - return m_pointer; - } - - bool hasData() const noexcept{ - return m_pointer; - } - - operator bool() const noexcept{ - return m_pointer; - } - -private: - void unlock() noexcept{ - if (m_handle){ - Detail::unlock(m_handle); - } - } - - Handle m_handle; - T* m_pointer; - -}; - -/// Owns a handle and frees it upon destruction, -/// unless `release` is called beforehand. -class UniqueHandle { - -public: - constexpr UniqueHandle(Handle h = Handle()) noexcept : - m_handle(h){} - - ~UniqueHandle(){ - free(); - } - - UniqueHandle(const UniqueHandle&) = delete; - UniqueHandle& operator=(const UniqueHandle&) = delete; - - UniqueHandle(UniqueHandle&& o) noexcept : - m_handle(o.m_handle){ - - o.m_handle = Handle(); - } - - UniqueHandle& operator=(UniqueHandle&& o) noexcept{ - if (&o != this){ - free(); - - m_handle = o.m_handle; - - o.m_handle = Handle(); - } - - return *this; - } - - operator bool() const noexcept{ - return m_handle; - } - - /// The contained handle. - Handle get() noexcept{ - return m_handle; - } - - /// The contained handle. - Handle get() const noexcept{ - return m_handle; - } - - /// Releases the contained handle, making the user responsible for freeing it. - Handle release() noexcept{ - Handle ret = m_handle; - m_handle = Handle(); - return ret; - } - - template - Lock lock() const{ - return m_handle; - } - -private: - void free() noexcept{ -#if defined(TWPP_IS_DS) - if (m_handle && m_handle != GlobalMemFuncs::doNotFreeHandle){ -#else - if (m_handle){ -#endif - Detail::free(m_handle); - } - } - - Handle m_handle; - -}; - -} - -} - -#endif // TWPP_DETAIL_FILE_MEMORYOPS_HPP - diff --git a/twain/twain/twpp/palette8.hpp b/twain/twain/twpp/palette8.hpp deleted file mode 100644 index 71a05bc..0000000 --- a/twain/twain/twpp/palette8.hpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_PALETTE8_HPP -#define TWPP_DETAIL_FILE_PALETTE8_HPP - -#include "../twpp.hpp" - - -namespace Twpp { - -namespace Detail { - -// specialization for Element8 -// we also want to set index of the element when placing it inside array -template -struct FixedArrayData > { - - static constexpr Element8 updateIndex(UInt8 index, const Element8& e) noexcept{ - return Element8(index, e.channel1(), e.channel2(), e.channel3()); - } - - template - constexpr FixedArrayData(const Element8(& arr)[inputSize]) noexcept : - m_arr{updateIndex(i, FixedArrayFlat(arr)[i])...}{} - - constexpr FixedArrayData() noexcept : - m_arr{Element8(i)...}{} - - Element8 m_arr[arraySize]; - -}; - -} - - -TWPP_DETAIL_PACK_BEGIN -/// Palette information for memory transfers -class Palette8 { - -public: - enum class Type : UInt16 { - Rgb = 0, - Gray = 1, - Cmy = 2 - }; - - typedef Element8 Element8Arr256[256]; - - /// Creates an uninitialized palette. - constexpr Palette8() noexcept : - m_size(0), m_type(Type::Rgb), m_colors(){} - - /// Creates a palette with the supplied type and elements. - template - constexpr Palette8(Type type, const Element8(& colors)[inputSize]) noexcept : - m_size(inputSize), m_type(type), - m_colors(colors){ - - static_assert(inputSize <= 256, "too many colors"); - } - - /// Creates a palette with the supplied type and elements from container. - /// \throw RangeException When there are more than 256 colors. - template - Palette8(Type type, const Container& colors) : - m_size(static_cast(colors.size())), m_type(type){ - - if (colors.size() > 256){ - throw RangeException(); - } - - auto& array = m_colors.array(); - for (UInt16 i = 0; i < m_size; i++){ - array[i] = colors[i]; - array[i].setIndex(i); - } - } - - /// Creates a palette with the supplied type and elements. - /// \throw RangeException When there are more than 256 colors. - Palette8(Type type, const Element8* colors, UInt16 size) : - m_size(size), m_type(type){ - - if (m_size > 256){ - throw RangeException(); - } - - auto& array = m_colors.array(); - for (UInt16 i = 0; i < m_size; i++){ - array[i] = colors[i]; - array[i].setIndex(static_cast(i)); // 0..255 max - } - } - - /// Number of elements in the palette. - constexpr UInt16 size() const noexcept{ - return m_size; - } - - /// Type of palette data. - constexpr Type type() const noexcept{ - return m_type; - } - - /// Array of palette elements. - constexpr const Element8Arr256& colors() const noexcept{ - return m_colors.array(); - } - -private: - UInt16 m_size; - Type m_type; - Detail::FixedArray m_colors; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_PALETTE8_HPP - diff --git a/twain/twain/twpp/passthrough.hpp b/twain/twain/twpp/passthrough.hpp deleted file mode 100644 index 49c33fd..0000000 --- a/twain/twain/twpp/passthrough.hpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_PASSTHROUGH_HPP -#define TWPP_DETAIL_FILE_PASSTHROUGH_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Structure for raw comminication with device in source. -/// See manual for more information, DAT_PASSTHRU, MSG_PASSTHRU. -class PassThrough { - -public: - enum class Direction : Int32 { - Get = 1, - Set = 2 - }; - - constexpr PassThrough( - void* command, - UInt32 commandSize, - Direction direction, - void* data, - UInt32 dataSize, - UInt32 dataXfered - ) noexcept : - m_cmd(command), m_cmdSize(commandSize), - m_direction(direction), - m_data(data), m_dataSize(dataSize), m_dataXfered(dataXfered){} - - constexpr void* command() const noexcept{ - return m_cmd; - } - - constexpr UInt32 commandSize() const noexcept{ - return m_cmdSize; - } - - template - void setCommand(const Container& command) noexcept{ - m_cmd = command.data(); - m_cmdSize = sizeof(Container::value_type) * command.size(); - } - - void setCommand(void* command, UInt32 size) noexcept{ - m_cmd = command; - m_cmdSize = size; - } - - constexpr Direction direction() const noexcept{ - return m_direction; - } - - void setDirection(Direction direction) noexcept{ - m_direction = direction; - } - - constexpr void* data() const noexcept{ - return m_data; - } - - constexpr UInt32 dataSize() const noexcept{ - return m_dataSize; - } - - template - void setData(const Container& data) noexcept{ - m_data = data.data(); - m_dataSize = sizeof(Container::value_type) * data.size(); - m_dataXfered = 0; - } - - void setData(void* data, UInt32 dataSize) noexcept{ - m_data = data; - m_dataSize = dataSize; - m_dataXfered = 0; - } - - constexpr UInt32 dataXfered() const noexcept{ - return m_dataXfered; - } - - void setDataXfered(Int32 dataXfered) noexcept{ - m_dataXfered = dataXfered; - } - -private: - void* m_cmd; - UInt32 m_cmdSize; - Direction m_direction; - void* m_data; - UInt32 m_dataSize; - UInt32 m_dataXfered; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_PASSTHROUGH_HPP diff --git a/twain/twain/twpp/pendingxfers.hpp b/twain/twain/twpp/pendingxfers.hpp deleted file mode 100644 index 9ba875b..0000000 --- a/twain/twain/twpp/pendingxfers.hpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_PENDINGXFERS_HPP -#define TWPP_DETAIL_FILE_PENDINGXFERS_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Reports number of pending images, transfers. -class PendingXfers { - -public: - /// Job control settings. - enum class JobPatch : UInt32 { - None = 0x0000, - MidSeparator = 0x0001, - P1 = 0x0002, - P2 = 0x0003, - P3 = 0x0004, - P4 = 0x0005, - P6 = 0x0006, - PT = 0x0007 - }; - - /// Creates object to report number of pending transfers. - /// \param count Number of pending transfers. - /// \param patch Job control settings. - constexpr PendingXfers(UInt16 count = 0, JobPatch patch = JobPatch::None) noexcept : - m_count(count), m_eoj(patch){} - - /// Number of pending images/transfers. - constexpr UInt16 count() const noexcept{ - return m_count; - } - - /// Sets number of pending images/transfers. - void setCount(UInt16 count) noexcept{ - m_count = count; - } - - /// Job control settings. - constexpr JobPatch jobPatch() const noexcept{ - return m_eoj; - } - - /// Sets job control settings. - void setJobPatch(JobPatch eoj) noexcept{ - m_eoj = eoj; - } - -private: - UInt16 m_count; - JobPatch m_eoj; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_PENDINGXFERS_HPP diff --git a/twain/twain/twpp/setupfilexfer.hpp b/twain/twain/twpp/setupfilexfer.hpp deleted file mode 100644 index f4a4a2f..0000000 --- a/twain/twain/twpp/setupfilexfer.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2017 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_SETUPFILEXFER_HPP -#define TWPP_DETAIL_FILE_SETUPFILEXFER_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Structure for setting up file transfer. -class SetupFileXfer { - -public: - /// Creates zero-initialized instance. - constexpr SetupFileXfer() noexcept : - m_format(ImageFileFormat::Tiff), m_volRefNum(0){} - - /// Creates instance with set file path and format. - /// And volume reference number on Mac OS. - /// \param filePath Path to transfered file. - /// \param format File format. - /// \param vrn Volume reference number. Mac OS only. - constexpr SetupFileXfer( - const Str255& filePath, - ImageFileFormat format, - Int16 vrn -#if defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) - = -1 -#elif !defined(TWPP_DETAIL_OS_MAC) -# error "Volume reference number for your platform here" -#endif - ) noexcept : - m_filePath(filePath), m_format(format), - m_volRefNum(vrn){} - - /// Path to transfered file. - constexpr const Str255& filePath() const noexcept{ - return m_filePath; - } - - /// Sets path to transfered file. - void setFilePath(const Str255& filePath) noexcept{ - m_filePath = filePath; - } - - /// Format of the transfered file. - constexpr ImageFileFormat format() const noexcept{ - return m_format; - } - - /// Sets format of the transfered file. - void setFormat(ImageFileFormat format) noexcept{ - m_format = format; - } - - /// Volume reference number. - /// Mac OS only. - constexpr Int16 volumeReferenceNumber() const noexcept{ - return m_volRefNum; - } - - /// Sets volume reference number. - /// Mac OS only. - void setVolumeReferenceNumber(Int16 volumeReferenceNumber) noexcept{ - m_volRefNum = volumeReferenceNumber; - } - -private: - Str255 m_filePath; - ImageFileFormat m_format; - Int16 m_volRefNum; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_SETUPFILEXFER_HPP diff --git a/twain/twain/twpp/setupmemxfer.hpp b/twain/twain/twpp/setupmemxfer.hpp deleted file mode 100644 index e645f68..0000000 --- a/twain/twain/twpp/setupmemxfer.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_SETUPMEMXFER_HPP -#define TWPP_DETAIL_FILE_SETUPMEMXFER_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Structure for setting up memory transfer. -class SetupMemXfer { - -public: - /// Creates zero-initialized instance. - constexpr SetupMemXfer() noexcept : - m_minSize(0), m_maxSize(0), m_prefSize(0){} - - /// Creates an initialized instance with set minimal, maximal and preferred sizes. - /// Must be true, or the behaviour is undefined: minSize <= preferredSize <= maxSize - constexpr SetupMemXfer( - UInt32 minSize, - UInt32 maxSize, - UInt32 preferredSize - ) noexcept : - m_minSize(minSize), m_maxSize(maxSize), m_prefSize(preferredSize){} - - /// Minimal supported buffer size in bytes. - constexpr UInt32 minSize() const noexcept{ - return m_minSize; - } - - /// Sets minimal supported buffer size in bytes. - void setMinSize(UInt32 minSize) noexcept{ - m_minSize = minSize; - } - - /// Maximal supported buffer size in bytes. - constexpr UInt32 maxSize() const noexcept{ - return m_maxSize; - } - - /// Sets maximal supported buffer size in bytes. - void setMaxSize(UInt32 maxSize) noexcept{ - m_maxSize = maxSize; - } - - /// Preferred buffer size in bytes. - constexpr UInt32 preferredSize() const noexcept{ - return m_prefSize; - } - - /// Sets preferred buffer size in bytes. - void setPreferredSize(UInt32 prefSize) noexcept{ - m_prefSize = prefSize; - } - -private: - UInt32 m_minSize; - UInt32 m_maxSize; - UInt32 m_prefSize; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_SETUPMEMXFER_HPP diff --git a/twain/twain/twpp/status.hpp b/twain/twain/twpp/status.hpp deleted file mode 100644 index 7d72a5f..0000000 --- a/twain/twain/twpp/status.hpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_STATUS_HPP -#define TWPP_DETAIL_FILE_STATUS_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Additional status information about a performed TWAIN operation. -class Status { - -public: - /// Creates operation status. - /// \param cond Status condition code. - /// \param data Additional status data, source-specific. - constexpr Status(CC cond = CC::Success, UInt16 data = 0) noexcept : - m_cond(cond), m_data(data){} - - /// Status condition code. - constexpr CC condition() const noexcept{ - return m_cond; - } - - /// Sets status condition code. - void setCondition(CC cc) noexcept{ - m_cond = cc; - } - - /// Aditional status data, source-specific. - constexpr UInt16 data() const noexcept{ - return m_data; - } - - /// Sets aditional status data, source-specific. - void setData(UInt16 data) noexcept{ - m_data = data; - } - - constexpr operator CC() const noexcept{ - return m_cond; - } - - constexpr operator bool() const noexcept{ - return success(m_cond); - } - - constexpr bool operator==(CC o) const noexcept{return m_cond == o;} - constexpr bool operator!=(CC o) const noexcept{return m_cond != o;} - - constexpr bool operator==(Status o) const noexcept{return m_cond == o.m_cond && m_data == o.m_data;} - constexpr bool operator!=(Status o) const noexcept{return m_cond != o.m_cond || m_data != o.m_data;} - - -private: - CC m_cond; - UInt16 m_data; - -}; - -static inline constexpr bool success(Status stat) noexcept{ - return stat; -} - -/// Structure for translating status to UTF8 text. -class StatusUtf8 { - -public: - typedef Detail::Lock ConstString; - - - /// Creates a status utf8 without string data. - StatusUtf8(Status status = Status()) noexcept : - m_status(status), m_size(0), m_string(){} - - /// Creates a status utf8 containing copy of string data. - /// The string must be null-terminated. - /// \tparam inputSize Size of the string including null terminator. - /// \param str The string, must be null-terminated. - /// \throw std::bad_alloc - template - StatusUtf8(Status status, const char(& str)[inputSize]) : - m_status(status), m_size(inputSize), m_string(Detail::alloc(inputSize)){ - - std::copy(str, str + inputSize, string().data()); - } - - /// Creates a new status utf8 containing a copy of the supplied string. - /// \param status - /// \param str Utf-8 string to copy, must be null-terminated. - /// \throw RangeException When string is too long, could not insert null terminator. - /// \throw std::bad_alloc - StatusUtf8(Status status, const char* str) : - m_status(status), m_size(0), m_string(){ - - auto len = strlen(str); - if (len >= std::numeric_limits::max()){ - throw RangeException(); - } - - m_size = static_cast(len) + 1; - m_string = Detail::alloc(m_size); - std::copy(str, str + len + 1, m_string.lock().data()); - } - - /// Creates a new status utf8 containing a copy of the supplied string. - /// \param status - /// \param str Utf-8 string to copy. - /// \throw RangeException When string is too long, could not insert null terminator. - /// \throw std::bad_alloc - StatusUtf8(Status status, const std::string& str) : - m_status(status), m_size(0), m_string(){ - - auto len = str.length(); - if (len >= std::numeric_limits::max()){ - throw RangeException(); - } - - m_size = static_cast(len) + 1; - m_string = Detail::alloc(m_size); - - auto lock = m_string.lock(); - std::copy(str.cbegin(), str.cend(), lock.data()); - lock[len] = '\0'; - } - - /// Creates a new StatusUtf8 containing a copy of the supplied string. - /// \param status - /// \param str Utf-8 string to copy, null terminator is not required. - /// \param strSize {Number of bytes to copy including null terminator. - /// Null terminator is inserted automatically.} - /// \throw RangeException When string is too short to satisfy the requested size. - /// \throw std::bad_alloc - StatusUtf8(Status status, const char* str, UInt32 strSize) : - m_status(status), m_size(0), m_string(){ - - auto len = strlen(str); - if (len < strSize){ - throw RangeException(); - } - - m_size = static_cast(strSize) + 1; - m_string = Detail::alloc(m_size); - - auto lock = m_string.lock(); - std::copy(str, str + strSize, lock.data()); - lock[strSize] = '\0'; - } - - StatusUtf8(const StatusUtf8&) = delete; - StatusUtf8& operator=(const StatusUtf8&) = delete; - - StatusUtf8(StatusUtf8&& o) noexcept : - m_status(o.m_status), m_size(o.m_size), m_string(std::move(o.m_string)){ - - o.m_status = Status(); - o.m_size = 0; - } - - StatusUtf8& operator=(StatusUtf8&& o) noexcept{ - if (&o != this){ - m_status = o.m_status; - m_size = o.m_size; - m_string = std::move(o.m_string); - - o.m_status = Status(); - o.m_size = 0; - } - - return *this; - } - - /// Returns the interpreted status. - Status status() const noexcept{ - return m_status; - } - - /// Sets the status to be interpreted. - void setStatus(Status status) noexcept{ - m_status = status; - } - - /// Returns the total number of bytes including null byte. - UInt32 size() const noexcept{ - return m_string ? m_size : 0; - } - - /// The UTF8 string itself. - ConstString string() const noexcept{ - return m_string.lock(); - } - -private: - Status m_status; - UInt32 m_size; - Detail::UniqueHandle m_string; - -}; - -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_STATUS_HPP - diff --git a/twain/twain/twpp/strings.hpp b/twain/twain/twpp/strings.hpp deleted file mode 100644 index 8698402..0000000 --- a/twain/twain/twpp/strings.hpp +++ /dev/null @@ -1,310 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2017 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_STRINGS_HPP -#define TWPP_DETAIL_FILE_STRINGS_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -// specialization for twain strings -// on mac os, these strings do not contain null terminator -// instead, the first byte contains the length -template -struct FixedArrayData > { - - template - constexpr FixedArrayData(const char(& arr)[inputSize]) noexcept : - m_arr{ -#if defined(TWPP_DETAIL_OS_MAC) - unsignedToSigned(inputSize - 1), -#elif !defined(TWPP_DETAIL_OS_WIN) && !defined(TWPP_DETAIL_OS_LINUX) -# error "string data setup for yout platform here" -#endif - FixedArrayFlat(arr)[i]... - }{} - - constexpr FixedArrayData() noexcept : - m_arr(){} - - char m_arr[arraySize]; - -}; - -// specialization for twain strings -// on mac os, these strings do not contain null terminator -// instead, the first byte contains the length -// so we provide one less index for the fixed array -// on windows, its element is zero-initialized due to it not being specified -// on mac os, the first byte contains the length, so the index is not used anyway -template -struct FixedArray : public FixedArrayData::Result> { - - typedef FixedArrayData::Result> ParentType; - typedef char Array[arraySize]; - - constexpr FixedArray() noexcept : - ParentType(){} - - template - constexpr FixedArray(const char(& arr)[inputSize]) noexcept : - ParentType(arr){ - - static_assert(inputSize <= arraySize, "string literal is too long"); - } - - constexpr const Array& array() const noexcept{ - return ParentType::m_arr; - } - - Array& array() noexcept{ - return ParentType::m_arr; - } - -}; - -/// TWAIN string template. -/// \tparam arraySize String capacity, including either null byte, or length byte (Mac OS). -template -class Str : private FixedArray{ - - typedef FixedArray DataType; - -public: - typedef const char* const_iterator; - typedef char* iterator; - - /// Maximal number of characters this string may hold. - /// Excluding null byte (length byte). - static constexpr UInt32 maxSize() noexcept{ - return arraySize - 1; - } - - static_assert(maxSize() <= std::numeric_limits::max(), "string type exceeds allowed sizes"); - - - /// Creates an empty, zero-initialized string. - constexpr Str() noexcept{} - - /// Creates a compile-time string from string literal (or char array). - /// \tparam inputSize Size of the string literal including null terminator. - /// \param str The string literal. - template - constexpr Str(const char(& str)[inputSize]) noexcept : - DataType(str){ - - static_assert(inputSize <= arraySize, "string literal is too long"); - } - - /// Alias to length(). - constexpr UInt32 size() const noexcept{ - return length(); - } - - /// Length of the string (number of 8-bit characters). - /// O(1) on Mac OS, O(n) anywhere else. - constexpr UInt32 length() const noexcept{ -#if defined(TWPP_DETAIL_OS_MAC) - return static_cast(this->array()[0]); -#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) - return strLen(data()); -#else -# error "String::length for your platform here" -#endif - } - - /// Pointer to constant data. - /// On Mac OS, the data is NOT null-terminated, - /// and points to the first character after size byte. - /// This operation is unsafe, and its use may not be platform-independent. - constexpr const char* data() const noexcept{ -#if defined(TWPP_DETAIL_OS_MAC) - return this->array() + 1; -#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) - return this->array(); -#else -# error "String::data for your platform here" -#endif - } - - /// Pointer to data. - /// On Mac OS, the data is NOT null-terminated, - /// and points to the first character after size byte. - /// This operation is unsafe, and its use may not be platform-independent. - char* data() noexcept{ -#if defined(TWPP_DETAIL_OS_MAC) - return this->array() + 1; -#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) - return this->array(); -#else -# error "String::data for your platform here" -#endif - } - - /// Sets string data. - /// Copies as much data as possible, discarding the rest. - /// The data needn't be null terminated. - /// \param str Data to copy. - /// \param size Maximal number of bytes to copy. - /// \return Number of bytes copied - the new length of this string. - UInt32 setData(const char* data, UInt32 size) noexcept{ - char* arr = this->data(); - UInt32 i = 0; - - auto maxLen = std::min(maxSize(), size); - for ( ; i < maxLen && *data; i++, data++){ - arr[i] = *data; - } - -#if defined(TWPP_DETAIL_OS_MAC) - *reinterpret_cast(this->array()) = static_cast(i); -#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) - arr[i] = '\0'; -#else -# error "String::setData for your platform here" -#endif - - return i; - } - - /// Sets string data. - /// Copies as much data as possible, discarding the rest. - /// The string must be null terminated. - /// \param str String to copy. - /// \return Number of characters copied - the new length of this string. - UInt32 setData(const char* str) noexcept{ - return setData(str, maxSize()); - } - - /// Sets string data from container (e.g. std::string). - /// Copies as much data as possible, discarding the rest. - /// The string needn't be null terminated. - /// \tparam Contaier Container type. - /// \param cont Container with data to be copied. - /// \return Number of characters copied - the new length of this string. - template::value>::type> - UInt32 setData(const Container& cont) noexcept{ - return setData(cont.data(), static_cast(std::min(cont.size(), maxSize()))); - } - - char operator[](UInt32 i) const noexcept{ - return data()[i]; - } - - char& operator[](UInt32 i) noexcept{ - return data()[i]; - } - - iterator begin() noexcept{ - return data(); - } - - constexpr const_iterator begin() const noexcept{ - return cbegin(); - } - - constexpr const_iterator cbegin() const noexcept{ - return data(); - } - - iterator end() noexcept{ - return data() + length(); - } - - constexpr const_iterator end() const noexcept{ - return cend(); - } - - constexpr const_iterator cend() const noexcept{ - return data() + length(); - } - - std::string string() const{ - return std::string(cbegin(), cend()); - } - -}; - -} - -template -constexpr bool operator==(const Detail::Str& a, const Detail::Str& b) noexcept{ - // length() is O(1) on mac os, O(n) anywhere else -#if defined(TWPP_DETAIL_OS_MAC) - return a.length() == b.length() && Detail::strCmp(a.data(), b.data()) == 0; -#elif defined(TWPP_DETAIL_OS_WIN) || defined(TWPP_DETAIL_OS_LINUX) - return Detail::strCmp(a.data(), b.data()) == 0; -#else -# error "String equals operator for your platform here" -#endif - -} - -template -constexpr bool operator<(const Detail::Str& a, const Detail::Str& b) noexcept{ - return Detail::strCmp(a.data(), b.data()) < 0; -} - -template -constexpr bool operator>(const Detail::Str& a, const Detail::Str& b) noexcept{ - return Detail::strCmp(a.data(), b.data()) > 0; -} - -template -constexpr bool operator!=(const Detail::Str& a, const Detail::Str& b) noexcept{ - return !(a == b); -} - -template -constexpr bool operator<=(const Detail::Str& a, const Detail::Str& b) noexcept{ - return !(a > b); -} - -template -constexpr bool operator>=(const Detail::Str& a, const Detail::Str& b) noexcept{ - return !(a < b); -} - -/// TWAIN string that can contain up to 33 characters (bytes). -typedef Detail::Str<34> Str32; - -/// TWAIN string that can contain up to 65 characters (bytes). -typedef Detail::Str<66> Str64; - -/// TWAIN string that can contain up to 129 characters (bytes). -typedef Detail::Str<130> Str128; - -/// TWAIN string that can contain up to 255 characters (bytes). -typedef Detail::Str<256> Str255; - -} - - -#endif // TWPP_DETAIL_FILE_STRINGS_HPP - diff --git a/twain/twain/twpp/twglue.hpp b/twain/twain/twpp/twglue.hpp deleted file mode 100644 index be5b549..0000000 --- a/twain/twain/twpp/twglue.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef TWGLUE_HPP -#define TWGLUE_HPP - -#include -// #include "Device/PublicFunc.h" - -struct TwGlue { - - TwGlue(const std::function& scan, const std::function& cancel) : - m_scan(scan), m_cancel(cancel){} - - std::function m_scan; - std::function m_cancel; - -}; - -#endif // TWGLUE_HPP diff --git a/twain/twain/twpp/types.hpp b/twain/twain/twpp/types.hpp deleted file mode 100644 index ef01d75..0000000 --- a/twain/twain/twpp/types.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_TYPES_HPP -#define TWPP_DETAIL_FILE_TYPES_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -typedef std::uintptr_t UIntPtr; -typedef std::uint8_t UInt8; -typedef std::uint16_t UInt16; -typedef std::uint32_t UInt32; -typedef std::int8_t Int8; -typedef std::int16_t Int16; -typedef std::int32_t Int32; - -/// Boolean value. -/// Implemented as a class to provide better type safety. -class Bool { - -public: - constexpr Bool(bool value = false) noexcept : - m_value(value){} - - constexpr operator bool() const noexcept{ - return m_value != 0; - } - -private: - Int16 m_value; - -}; - -/// Handle to memory area. -/// Implemented as a class to provide better type safety. -class Handle { - -public: - typedef Detail::RawHandle Raw; - - constexpr explicit Handle(Raw raw = Raw()) noexcept : - m_raw(raw){} - - /// Underlying OS-dependent handle. - constexpr Raw raw() const noexcept{ - return m_raw; - } - - constexpr operator bool() const noexcept{ - return m_raw != Raw(); - } - -private: - Raw m_raw; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_TYPES_HPP - diff --git a/twain/twain/twpp/typesops.hpp b/twain/twain/twpp/typesops.hpp deleted file mode 100644 index 3c187fd..0000000 --- a/twain/twain/twpp/typesops.hpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_TYPESOPS_HPP -#define TWPP_DETAIL_FILE_TYPESOPS_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -/// Enumeration representing basic types. -enum class Type : UInt16 { - DontCare = 0xFFFF, - Int8 = 0x0000, - Int16 = 0x0001, - Int32 = 0x0002, - UInt8 = 0x0003, - UInt16 = 0x0004, - UInt32 = 0x0005, - Bool = 0x0006, - Fix32 = 0x0007, - Frame = 0x0008, - Str32 = 0x0009, - Str64 = 0x000a, - Str128 = 0x000b, - Str255 = 0x000c, - Handle = 0x000f -}; - -/// Whether the enum value actually is a type, DontCare is not a type. -static inline bool isType(Type type){ - switch (type){ - case Type::Int8: - case Type::UInt8: - case Type::Int16: - case Type::UInt16: - case Type::Int32: - case Type::UInt32: - case Type::Bool: - case Type::Fix32: - case Type::Str32: - case Type::Str64: - case Type::Str128: - case Type::Str255: - case Type::Frame: - case Type::Handle: - return true; - - default: - return false; - } -} - -/// Size in bytes of a type represented by enum value. -static inline UInt32 typeSize(Type type){ - switch (type){ - case Type::Int8: return sizeof(Int8); - case Type::UInt8: return sizeof(UInt8); - case Type::Int16: return sizeof(Int16); - case Type::UInt16: return sizeof(UInt16); - case Type::Int32: return sizeof(Int32); - case Type::UInt32: return sizeof(UInt32); - case Type::Bool: return sizeof(Bool); - case Type::Fix32: return sizeof(Fix32); - case Type::Str32: return sizeof(Str32); - case Type::Str64: return sizeof(Str64); - case Type::Str128: return sizeof(Str128); - case Type::Str255: return sizeof(Str255); - case Type::Frame: return sizeof(Frame); - case Type::Handle: return sizeof(Handle); - default: throw TypeException(); - } -} - -namespace Detail { - -/// Conversion from Type enum to actual data type. -template struct Twty {}; -template<> struct Twty {typedef Int8 Type;}; -template<> struct Twty {typedef Int16 Type;}; -template<> struct Twty {typedef Int32 Type;}; -template<> struct Twty {typedef UInt8 Type;}; -template<> struct Twty {typedef UInt16 Type;}; -template<> struct Twty {typedef UInt32 Type;}; -template<> struct Twty {typedef Bool Type;}; -template<> struct Twty {typedef Fix32 Type;}; -template<> struct Twty {typedef Frame Type;}; -template<> struct Twty {typedef Str32 Type;}; -template<> struct Twty {typedef Str64 Type;}; -template<> struct Twty {typedef Str128 Type;}; -template<> struct Twty {typedef Str255 Type;}; -template<> struct Twty {typedef Handle Type;}; - - -// Conversion from data type to Type enum helpers. -template struct Tytw; - -template // true -struct TytwHelper : Tytw::type> {}; - -template -struct TytwHelper {}; - -/// Conversion from data type to Type enum. -template struct Tytw : TytwHelper::value> {}; -template<> struct Tytw {static constexpr const Type twty = Type::Int8;}; -template<> struct Tytw {static constexpr const Type twty = Type::Int16;}; -template<> struct Tytw {static constexpr const Type twty = Type::Int32;}; -template<> struct Tytw {static constexpr const Type twty = Type::UInt8;}; -template<> struct Tytw {static constexpr const Type twty = Type::UInt16;}; -template<> struct Tytw {static constexpr const Type twty = Type::UInt32;}; -template<> struct Tytw {static constexpr const Type twty = Type::Bool;}; -template<> struct Tytw {static constexpr const Type twty = Type::Fix32;}; -template<> struct Tytw {static constexpr const Type twty = Type::Frame;}; -template<> struct Tytw {static constexpr const Type twty = Type::Str32;}; -template<> struct Tytw {static constexpr const Type twty = Type::Str64;}; -template<> struct Tytw {static constexpr const Type twty = Type::Str128;}; -template<> struct Tytw {static constexpr const Type twty = Type::Str255;}; -template<> struct Tytw {static constexpr const Type twty = Type::Handle;}; - -} - -} - -#endif // TWPP_DETAIL_FILE_TYPESOPS_HPP - diff --git a/twain/twain/twpp/userinterface.hpp b/twain/twain/twpp/userinterface.hpp deleted file mode 100644 index ba42bcd..0000000 --- a/twain/twain/twpp/userinterface.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015-2017 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_USERINTERFACE_HPP -#define TWPP_DETAIL_FILE_USERINTERFACE_HPP - -#include "../twpp.hpp" - -namespace Twpp { - -TWPP_DETAIL_PACK_BEGIN -/// Structure holding parameters for enabling or disabling data source. -class UserInterface { - -public: - /// Creates a new UserInterface. - /// \param showUi Whether to show internal DS GUI. Disabling DS GUI might not be supported. - /// \param modalUi Whether DS GUI should be modal. Not used on Linux. Might not be supported on Windows. - /// \param parent Windows-only, others set to null. Handle to parent window. This object does NOT take ownership. -#if defined(TWPP_DETAIL_OS_WIN) - constexpr UserInterface(Bool showUi, Bool modalUi, Handle parent) noexcept : - m_showUi(showUi), m_modalUi(modalUi), m_parent(parent){} -#elif defined(TWPP_DETAIL_OS_MAC) || defined(TWPP_DETAIL_OS_LINUX) - constexpr UserInterface(Bool showUi, Bool modalUi, Handle parent = Handle()) noexcept : - m_showUi(showUi), m_modalUi(modalUi), m_parent(parent){} -#else -# error "UserInterface constructor for your platform here" -#endif - - /// Whether to show internal DS GUI. - constexpr Bool showUi() const noexcept{ - return m_showUi; - } - - /// Whether DS GUI should be modal - constexpr Bool modalUi() const noexcept{ - return m_modalUi; - } - - /// Handle to parent window. - constexpr Handle parent() const noexcept{ - return m_parent; - } - -private: - Bool m_showUi; - Bool m_modalUi; - Handle m_parent; - -}; -TWPP_DETAIL_PACK_END - -} - -#endif // TWPP_DETAIL_FILE_USERINTERFACE_HPP - diff --git a/twain/twain/twpp/utils.hpp b/twain/twain/twpp/utils.hpp deleted file mode 100644 index 5eb122c..0000000 --- a/twain/twain/twpp/utils.hpp +++ /dev/null @@ -1,485 +0,0 @@ -/* - -The MIT License (MIT) - -Copyright (c) 2015 Martin Richter - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -#ifndef TWPP_DETAIL_FILE_UTILS_HPP -#define TWPP_DETAIL_FILE_UTILS_HPP - -#undef max -#undef min -#include -#include "../twpp.hpp" - -namespace Twpp { - -namespace Detail { - -/// Creates a template for testing whether a class contains public static method. -/// Use this macro anywhere a class may be defined, and pass method name -/// as its parameter. Then use `HasStaticMethod_` template. -/// -/// E. g.: -/// TWPP_DETAIL_CREATE_HAS_STATIC_METHOD(myMethod) // <- semicolon not required -/// HasStaticMethod_myMethod::value -/// -/// This test whether `MyClass` has static method `void MyClass::myMethod(int, char)`. -/// That is whether you may do this: -/// MyClass::myMethod(10, 'a'); -#define TWPP_DETAIL_CREATE_HAS_STATIC_METHOD(methodName) \ - template\ - class HasStaticMethod_ ## methodName;\ - \ - template\ - class HasStaticMethod_ ## methodName {\ - \ - template\ - static constexpr auto test(U*) ->\ - typename std::is_same()...)), Ret>::type;\ - \ - template\ - static constexpr std::false_type test(...);\ - \ - public:\ - typedef decltype(test(0)) type;\ - static constexpr const bool value = type::value;\ - \ - }; - -/// Creates a template for testing whether a class contains public method. -/// Use this macro anywhere a class may be defined, and pass method name -/// as its parameter. Then use `HasMethod_` template. -/// -/// E. g.: -/// TWPP_DETAIL_CREATE_HAS_METHOD(myMethod) // <- semicolon not required -/// HasMethod_myMethod::value -/// -/// This test whether `MyClass` has method (AKA member function) `void MyClass::myMethod(int, char)`. -/// That is whether you may do this: -/// MyClass o ... ; -/// o.myMethod(10, 'a'); -#define TWPP_DETAIL_CREATE_HAS_METHOD(methodName) \ - template\ - class HasMethod_ ## methodName;\ - \ - template\ - class HasMethod_ ## methodName {\ - \ - template\ - static constexpr auto test(U*) ->\ - typename std::is_same().methodName(std::declval()...)), Ret>::type;\ - \ - template\ - static constexpr std::false_type test(...);\ - \ - public:\ - typedef decltype(test(0)) type;\ - static constexpr const bool value = type::value;\ - \ - }; - -/// Performs a pointer type cast, suppresses strict aliasing warnings. -/// \tparam T Type of the returned pointer. Must be pointer type (e.g. `char*`). -/// \param ptr Pointer to be cast. -/// \return Cast pointer. -template -static constexpr inline T alias_cast(void* ptr) noexcept{ - return reinterpret_cast(ptr); -} - -/// Performs a constant pointer type cast, suppresses strict aliasing warnings. -/// \tparam T Type of the returned pointer. Must be pointer type (e.g. `char*`). -/// \param ptr Pointer to be cast. -/// \return Cast pointer. -template -static constexpr inline T alias_cast(const void* ptr) noexcept{ - return reinterpret_cast(ptr); -} - -/// Suppresses warnings about unused parameters or arguments. -/// \tparam Args List of argument types. No need to specify explicitly. -template -static inline void unused(const Args& ...) noexcept{} - - - -// CODE FROM http://www.macieira.org/blog/2011/07/initialising-an-array-with-cx0x-using-constexpr-and-variadic-templates/ -// BEGIN -template struct IndexList {}; - -template struct Append; -template -struct Append, Right>{ typedef IndexList Result; }; - -template struct Indexes { - typedef typename Append::Result, N - 1>::Result Result; -}; -template<> struct Indexes<0> { typedef IndexList<> Result; }; -// END - -/// Converts an array of arbitary size to array-like recursive structure of fixed size (at compile time). -/// Provide template specialization if special handling of elements is required, and you do care -/// about their positions - otherwise see FixedArrayData below. -/// \tparam T Element type. -/// \tparam arraySize Number of elements in the fixed array. -template -struct FixedArrayFlat : FixedArrayFlat { - - /// The index this structure (with this `arraySize`) holds. - static constexpr const std::size_t g_index = arraySize - 1; - - /// Performs the conversion from arbiraty-size array to fixed-size structure. - /// We use left recursion to initialize values of all inherited structures first. - /// Then the value of this one is initialized, either copied from the input array itself, - /// or default-initialized in case the array is not large enough. - /// \tparam inputSize {Size of the input array. If smaller than the fixed array, - /// excessive elements are default-initialized (may be changed in specializations). - /// Providing larger array results in undefined behaviour.} - /// \param arr The arbitary-size array. - template - constexpr inline FixedArrayFlat(const T(& arr)[inputSize]) noexcept : - FixedArrayFlat(arr), m_val(g_index < inputSize ? arr[g_index] : T()){} - - /// Returns value contained at specific index. - /// If the index if smaller than the size of the input array, a value is returned - /// as if the operation was performed on that array. Otherwise a default value - /// of the type `T` is returned (or anything else a specialization provides). - /// Behaviour of this operator is undefined if the index equals to or is greater than - /// the size of the fixed array. - /// \param i Value index. - /// \return Value at index. - constexpr inline T operator[](std::size_t i) const noexcept{ - return i == g_index ? m_val : FixedArrayFlat::operator [](i); - } - - /// Value held by this structure. - T m_val; - -}; - -/// Converts an array of arbitary size to array-like recursive structure of fixed size (at compile time). -/// This template specialization terminates the recursion. -/// No need to provide any further specializations. -/// \tparam T Element type. -template -struct FixedArrayFlat { - - template - constexpr inline FixedArrayFlat(const T(&)[inputSize]) noexcept{} - - constexpr inline T operator[](std::size_t) const noexcept{ - return T(); - } - -}; - - -/// Converts an array of arbitary size to array of fixed size at compile time. -/// The job itself is done in the specialization below. -/// \tparam T Element type. -/// \tparam arraySize Number of elements in the fixed array. -/// \tparam IndexList Type holding indexes of the fixed array. -template -struct FixedArrayData {}; - -/// Converts an array of arbitary size to array of fixed size at compile time. -/// Provide template specialization if special handling of elements is required, and you -/// don't care about their positions. -/// \tparam T Element type. -/// \tparam arraySize Number of elements in the fixed array. -/// \tparam i Indexes of the fixed array. -template -struct FixedArrayData > { - - /// Performs the conversion from arbiraty-size array to fixed-size array. - /// Uses FixedArrayFlat to extend the input array to desired size. - /// \tparam inputSize Size of the input array. - /// \param arr The input array. - template - constexpr FixedArrayData(const T(& arr)[inputSize]) noexcept : - m_arr{FixedArrayFlat(arr)[i]...}{} - - /// Creates default-initialized array. - constexpr FixedArrayData() noexcept : - m_arr(){} - - /// The fixed array. - T m_arr[arraySize]; - -}; - -/// Compile-time constructible fixed-size array of type `T` and length `arraySize`. -/// The array can be constructed from variable-sized array -/// of up to `arraySize` elements at compile time. -/// \tparam T Element type. -/// \tparam arraySize Number of elements in the array. -template -struct FixedArray : public FixedArrayData::Result> { - - typedef FixedArrayData::Result> ParentType; - typedef T Array[arraySize]; - - /// Creates default-initialized array. - constexpr FixedArray() noexcept : - ParentType(){} - - /// Creates fixed-size array from variable-size array at compile time. - /// If the size of input array exceeds `arraySize`, a compile-time error is emited. - /// \tparam inputSize Number of elements of the input array. - /// \param arr The input array. - template - constexpr FixedArray(const T(& arr)[inputSize]) noexcept : - ParentType(arr){ - - static_assert(inputSize <= arraySize, "array literal is too big"); - } - - /// The contained array. - constexpr const Array& array() const noexcept{ - return ParentType::m_arr; - } - - /// The contained array. - Array& array() noexcept{ - return ParentType::m_arr; - } - -}; - -/// Joins two arrays at compile time. -/// The job itself is done in the specialization below. -/// \tparam T Element type. -/// \tparam lenA Size of the first array. -/// \tparam lenB Size of the second array. -/// \tparam IndexList Type holding indexes of the resulting array. -template -struct ArrayJoinData {}; - -/// Joins two arrays at compile time. -/// The result of this operation is an array that contains all the elements -/// from the first array immediately followed by all the elements from -/// the second array. -/// \tparam T Element type. -/// \tparam lenA Size of the first array. -/// \tparam lenB Size of the second array. -/// \tparam i Indexes of the resulting array. -template -struct ArrayJoinData > { - - /// Performs the join operation. - /// \param a The first array. - /// \param b The second array. - constexpr ArrayJoinData(const T(& a)[lenA], const T(& b)[lenB]) noexcept : - m_arr{(i < lenA ? a[i] : b[i - lenA])...}{} - - /// The resulting array. - T m_arr[lenA + lenB]; - -}; - -/// Compile-time join operation of two arrays of the same type. -/// \tparam T Element type. -/// \tparam lenA Size of the first array. -/// \tparam lenB Size of the second array. -template -struct ArrayJoin : public ArrayJoinData::Result> { - - typedef ArrayJoinData::Result> ParentType; - typedef T Array[lenA + lenB]; - - /// Performs the join operation. - /// \param a The first array. - /// \param b The second array. - constexpr ArrayJoin(const T(& a)[lenA], const T(& b)[lenB]) noexcept : - ParentType(a, b){} - - /// The joined array. - constexpr const Array& array() const noexcept{ - return ParentType::m_arr; - } - - /// The joined array. - Array& array() noexcept{ - return ParentType::m_arr; - } - -}; - -/// Performs compile-time array join operation. -/// This is a helper function, see ArrayJoin and ArrayJoinData for more info. -/// \tparam T Element type. -/// \tparam lenA Size of the first array. -/// \tparam lenB Size of the second array. -/// \param a The first array. -/// \param b The second array. -/// \return The joined array. -template -static constexpr inline ArrayJoin arrayJoin(const T(& a)[lenA], const T(& b)[lenB]) noexcept{ - return {a, b}; -} - - -/// The loop that checks the suffix at compile time, see endsWith below. -/// Checks are performed from right to left. -/// \tparam T Element type. -/// \tparam arrLen The size of the array to be checked for the suffix. -/// \tparam subLen The size of the suffix array. -/// \param arr The array to be checked for the suffix. -/// \param sub The suffix array. -/// \param endOff Offset from the last element to be checked in this call. -/// \return Whether the suffix is contained. -template -static constexpr inline bool endsWithLoop(const T(& arr)[arrLen], const T(& sub)[subLen], std::size_t endOff){ - return endOff >= subLen || (arr[arrLen - 1 - endOff] == sub[subLen - 1 - endOff] && endsWithLoop(arr, sub, endOff + 1)); -} - -/// Checks whether the input array contains supplied suffix at compile time. -/// \tparam T Element type. -/// \tparam arrLen The size of the array to be checked for the suffix. -/// \tparam subLen The size of the suffix array. -/// \param arr The array to be checked for the suffix. -/// \param sub The suffix array. -/// \return Whether the suffix is contained. -template -static constexpr inline bool endsWith(const T(& arr)[arrLen], const T(& sub)[subLen]){ - return arrLen >= subLen && endsWithLoop(arr, sub, 0); -} - -/// Implementation of compile-time C string length. -/// Uses tail recursion. -/// \param str The string, or its remaining part. -/// \param len Length of the previous, already processed, part of the string. -/// \return Length of the string. -static constexpr inline std::size_t strLenImpl(const char* str, std::size_t len = 0) noexcept{ - return *str == '\0' ? len : strLenImpl(str + 1, len + 1); -} - -/// Compile-time C string length. -/// \param str The string. -/// \return Length of the string. -static constexpr inline std::size_t strLen(const char* str) noexcept{ - return strLenImpl(str); -} - - -/// Unsigned to signed conversion, using static_cast. -/// Available only if integers are represented using 2 complement. -/// Specialization handles non-2 complement cases. -/// \tparam T An integral type. -/// \tparam _2complement Whether ints are represented as 2 complement. -template // true -struct UnsigToSig { - typedef typename std::make_signed::type Signed; - typedef typename std::make_unsigned::type Unsigned; - - static constexpr Signed convert(Unsigned val) noexcept{ - return static_cast(val); - } -}; - -/// Unsigned to signed conversion. -/// This specialization is used when architecture does not use 2 complement. -/// \tparam T An integral type. -template -struct UnsigToSig { - typedef typename std::make_signed::type Signed; - typedef typename std::make_unsigned::type Unsigned; - - static constexpr Signed convert(Unsigned val) noexcept{ - return val <= std::numeric_limits::max() ? - static_cast(val) : - static_cast(val - std::numeric_limits::min()) + std::numeric_limits::min(); - } -}; - -/// Converts, at compile time, an unsigned integer to its signed counterpart. -/// This holds true: unsignedValue == static_cast(unsignedToSigned(unsignedValue)) -/// \tparam T Unsigned integral type. -/// \param val Unsigned value to be converted to signed. -/// \return Signed value that can be converted back to its unsigned type. -template::value>::type> -static constexpr inline typename std::make_signed::type unsignedToSigned(T val) noexcept{ - typedef typename std::make_signed::type Signed; - typedef typename std::make_unsigned::type Unsigned; - - return UnsigToSig(-1) == static_cast(~Unsigned(0))>::convert(val); -} - -/// Compares two C strings at compile time as if strcmp was used. -/// \param a First string. -/// \param b Second string. -/// \return See strcmp. -static constexpr inline int strCmp(const char* a, const char* b) noexcept{ - return *a != *b ? (static_cast(*a) - *b) : (*a == '\0' ? 0 : strCmp(a + 1, b + 1)); -} - -/// Absolute value. -/// Default implementation handles signed values -/// of non-integral types. -/// \tparam T Data type. -/// \tparam integral Whether the type is integral. -/// \tparam unsig Whether the data type is unsigned. -template // false, false -struct Abs { - static constexpr inline T abs(T a) noexcept{ - return a >= T() ? a : -a; - } -}; - -/// Absolute value. -/// This handles signed values of integral types. -/// \tparam T Data type. -template -struct Abs { - static constexpr inline T abs(T a) noexcept{ - return std::abs(a); - } -}; - -/// Absolute value. -/// This handles unsigned values. -/// \tparam T Data type. -template -struct Abs { - static constexpr inline T abs(T a) noexcept{ - return a; - } -}; - -/// Absolute value. -/// Handles anything that has `bool operator >=(const T&)` (or equiv.), -/// `T operator-()`, and its default value represents `zero`. -/// \tparam T Data type. -/// \param a Value. -template -static constexpr inline T abs(T a) noexcept{ - return Abs::value, std::is_unsigned::value>::abs(a); -} - -} - -} - -#endif // TWPP_DETAIL_FILE_UTILS_HPP -