printing_plugin.cc 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Copyright (C) 2017, David PHAM-VAN <dev.nfet.net@gmail.com>
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "include/printing/printing_plugin.h"
  17. #include <cstring>
  18. #include <memory>
  19. #include <flutter_linux/flutter_linux.h>
  20. #include <gtk/gtk.h>
  21. #include "print_job.h"
  22. #define PRINTING_PLUGIN(obj) \
  23. (G_TYPE_CHECK_INSTANCE_CAST((obj), printing_plugin_get_type(), \
  24. PrintingPlugin))
  25. struct _PrintingPlugin {
  26. GObject parent_instance;
  27. };
  28. G_DEFINE_TYPE(PrintingPlugin, printing_plugin, g_object_get_type())
  29. static FlMethodChannel* channel;
  30. // Called when a method call is received from Flutter.
  31. static void printing_plugin_handle_method_call(PrintingPlugin* self,
  32. FlMethodCall* method_call) {
  33. g_autoptr(FlMethodResponse) response = nullptr;
  34. const gchar* method = fl_method_call_get_name(method_call);
  35. FlValue* args = fl_method_call_get_args(method_call);
  36. if (strcmp(method, "printingInfo") == 0) {
  37. g_autoptr(FlValue) result = print_job::printing_info();
  38. response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
  39. } else if (strcmp(method, "listPrinters") == 0) {
  40. g_autoptr(FlValue) result = print_job::list_printers();
  41. response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
  42. } else if (strcmp(method, "printPdf") == 0) {
  43. auto name = fl_value_get_string(fl_value_lookup_string(args, "name"));
  44. auto printerValue = fl_value_lookup_string(args, "printer");
  45. auto printer =
  46. printerValue == nullptr ? nullptr : fl_value_get_string(printerValue);
  47. auto jobNum = fl_value_get_int(fl_value_lookup_string(args, "job"));
  48. auto pageWidth = fl_value_get_float(fl_value_lookup_string(args, "width"));
  49. auto pageHeight =
  50. fl_value_get_float(fl_value_lookup_string(args, "height"));
  51. auto marginLeft =
  52. fl_value_get_float(fl_value_lookup_string(args, "marginLeft"));
  53. auto marginTop =
  54. fl_value_get_float(fl_value_lookup_string(args, "marginTop"));
  55. auto marginRight =
  56. fl_value_get_float(fl_value_lookup_string(args, "marginRight"));
  57. auto marginBottom =
  58. fl_value_get_float(fl_value_lookup_string(args, "marginBottom"));
  59. auto job = new print_job(jobNum);
  60. auto res = job->print_pdf(name, printer, pageWidth, pageHeight, marginLeft,
  61. marginTop, marginRight, marginBottom);
  62. if (!res) {
  63. delete job;
  64. }
  65. g_autoptr(FlValue) result = fl_value_new_int(res);
  66. response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
  67. } else if (strcmp(method, "sharePdf") == 0) {
  68. auto name = fl_value_get_string(fl_value_lookup_string(args, "name"));
  69. auto doc = fl_value_get_uint8_list(fl_value_lookup_string(args, "doc"));
  70. auto size = fl_value_get_length(fl_value_lookup_string(args, "doc"));
  71. auto res = print_job::share_pdf(doc, size, name);
  72. g_autoptr(FlValue) result = fl_value_new_int(res);
  73. response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
  74. } else if (strcmp(method, "rasterPdf") == 0) {
  75. auto doc = fl_value_get_uint8_list(fl_value_lookup_string(args, "doc"));
  76. auto size = fl_value_get_length(fl_value_lookup_string(args, "doc"));
  77. auto v_pages = fl_value_lookup_string(args, "pages");
  78. int32_t* pages = nullptr;
  79. size_t pages_count = 0;
  80. if (fl_value_get_type(v_pages) == FL_VALUE_TYPE_LIST) {
  81. pages_count = fl_value_get_length(v_pages);
  82. pages = (int32_t*)malloc(sizeof(int32_t) * pages_count);
  83. for (auto n = 0; n < pages_count; n++) {
  84. pages[n] = fl_value_get_int(fl_value_get_list_value(v_pages, n));
  85. }
  86. }
  87. auto scale = fl_value_get_float(fl_value_lookup_string(args, "scale"));
  88. auto jobNum = fl_value_get_int(fl_value_lookup_string(args, "job"));
  89. auto job = std::make_unique<print_job>(jobNum);
  90. job->raster_pdf(doc, size, pages, pages_count, scale);
  91. free(pages);
  92. g_autoptr(FlValue) result = fl_value_new_bool(true);
  93. response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
  94. } else {
  95. response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
  96. }
  97. fl_method_call_respond(method_call, response, nullptr);
  98. }
  99. static void printing_plugin_dispose(GObject* object) {
  100. G_OBJECT_CLASS(printing_plugin_parent_class)->dispose(object);
  101. }
  102. static void printing_plugin_class_init(PrintingPluginClass* klass) {
  103. G_OBJECT_CLASS(klass)->dispose = printing_plugin_dispose;
  104. }
  105. static void printing_plugin_init(PrintingPlugin* self) {}
  106. static void method_call_cb(FlMethodChannel* channel,
  107. FlMethodCall* method_call,
  108. gpointer user_data) {
  109. PrintingPlugin* plugin = PRINTING_PLUGIN(user_data);
  110. printing_plugin_handle_method_call(plugin, method_call);
  111. }
  112. void printing_plugin_register_with_registrar(FlPluginRegistrar* registrar) {
  113. PrintingPlugin* plugin =
  114. PRINTING_PLUGIN(g_object_new(printing_plugin_get_type(), nullptr));
  115. g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  116. channel = fl_method_channel_new(fl_plugin_registrar_get_messenger(registrar),
  117. "net.nfet.printing", FL_METHOD_CODEC(codec));
  118. fl_method_channel_set_method_call_handler(
  119. channel, method_call_cb, g_object_ref(plugin), g_object_unref);
  120. g_object_unref(plugin);
  121. }
  122. void on_page_rasterized(print_job* job,
  123. const uint8_t* data,
  124. size_t size,
  125. int width,
  126. int height) {
  127. g_autoptr(FlValue) map = fl_value_new_map();
  128. fl_value_set_string(map, "image", fl_value_new_uint8_list(data, size));
  129. fl_value_set_string(map, "width", fl_value_new_int(width));
  130. fl_value_set_string(map, "height", fl_value_new_int(height));
  131. fl_value_set_string(map, "job", fl_value_new_int(job->get_id()));
  132. fl_method_channel_invoke_method(channel, "onPageRasterized", map, nullptr,
  133. nullptr, nullptr);
  134. }
  135. void on_page_raster_end(print_job* job, const char* error) {
  136. g_autoptr(FlValue) map = fl_value_new_map();
  137. fl_value_set_string(map, "job", fl_value_new_int(job->get_id()));
  138. if (error != nullptr) {
  139. fl_value_set_string(map, "error", fl_value_new_string(error));
  140. }
  141. fl_method_channel_invoke_method(channel, "onPageRasterEnd", map, nullptr,
  142. nullptr, nullptr);
  143. }
  144. static void on_layout_response_cb(GObject* object,
  145. GAsyncResult* result,
  146. gpointer user_data) {
  147. print_job* job = static_cast<print_job*>(user_data);
  148. g_autoptr(GError) error = nullptr;
  149. g_autoptr(FlMethodResponse) response =
  150. fl_method_channel_invoke_method_finish(channel, result, &error);
  151. if (!response) {
  152. job->cancel_job(error->message);
  153. }
  154. if (FL_IS_METHOD_SUCCESS_RESPONSE(response)) {
  155. FlValue* result = fl_method_success_response_get_result(
  156. FL_METHOD_SUCCESS_RESPONSE(response));
  157. auto data = fl_value_get_uint8_list(result);
  158. auto size = fl_value_get_length(result);
  159. job->write_job(data, size);
  160. } else if (FL_IS_METHOD_ERROR_RESPONSE(response)) {
  161. FlMethodErrorResponse* error_response = FL_METHOD_ERROR_RESPONSE(response);
  162. // fl_method_error_response_get_code(error_response);
  163. auto message = fl_method_error_response_get_message(error_response);
  164. // fl_method_error_response_get_details(error_response);
  165. job->cancel_job(message);
  166. }
  167. }
  168. void on_layout(print_job* job,
  169. double pageWidth,
  170. double pageHeight,
  171. double marginLeft,
  172. double marginTop,
  173. double marginRight,
  174. double marginBottom) {
  175. g_autoptr(FlValue) map = fl_value_new_map();
  176. fl_value_set_string(map, "job", fl_value_new_int(job->get_id()));
  177. fl_value_set_string(map, "width", fl_value_new_float(pageWidth));
  178. fl_value_set_string(map, "height", fl_value_new_float(pageHeight));
  179. fl_value_set_string(map, "marginLeft", fl_value_new_float(marginLeft));
  180. fl_value_set_string(map, "marginTop", fl_value_new_float(marginTop));
  181. fl_value_set_string(map, "marginRight", fl_value_new_float(marginRight));
  182. fl_value_set_string(map, "marginBottom", fl_value_new_float(marginBottom));
  183. fl_method_channel_invoke_method(channel, "onLayout", map, nullptr,
  184. on_layout_response_cb, job);
  185. }
  186. void on_completed(print_job* job, bool completed, const char* error) {
  187. g_autoptr(FlValue) map = fl_value_new_map();
  188. fl_value_set_string(map, "job", fl_value_new_int(job->get_id()));
  189. fl_value_set_string(map, "completed", fl_value_new_bool(completed));
  190. if (error != nullptr) {
  191. fl_value_set_string(map, "error", fl_value_new_string(error));
  192. }
  193. fl_method_channel_invoke_method(channel, "onCompleted", map, nullptr, nullptr,
  194. nullptr);
  195. }