⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkcupsutils.c

📁 This GTK+ version 2.12.3. GTK+ is a multi-platform toolkit for creating graphical user interfaces.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GTK - The GIMP Toolkit * gtkcupsutils.h: Statemachine implementation of POST and GET  * cups calls which can be used to create a non-blocking cups API * Copyright (C) 2006, 2007 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include "config.h"#include "gtkcupsutils.h"#include "gtkdebug.h"#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#include <time.h>typedef void (*GtkCupsRequestStateFunc) (GtkCupsRequest *request);static void _connect            (GtkCupsRequest *request);static void _post_send          (GtkCupsRequest *request);static void _post_write_request (GtkCupsRequest *request);static void _post_write_data    (GtkCupsRequest *request);static void _post_check         (GtkCupsRequest *request);static void _post_read_response (GtkCupsRequest *request);static void _get_send           (GtkCupsRequest *request);static void _get_check          (GtkCupsRequest *request);static void _get_read_data      (GtkCupsRequest *request);struct _GtkCupsResult{  gchar *error_msg;  ipp_t *ipp_response;  GtkCupsErrorType error_type;  /* some error types like HTTP_ERROR have a status and a code */  int error_status;              int error_code;  guint is_error : 1;  guint is_ipp_response : 1;};#define _GTK_CUPS_MAX_ATTEMPTS 10 #define _GTK_CUPS_MAX_CHUNK_SIZE 8192static GtkCupsRequestStateFunc post_states[] = {  _connect,  _post_send,  _post_write_request,  _post_write_data,  _post_check,  _post_read_response};static GtkCupsRequestStateFunc get_states[] = {  _connect,  _get_send,  _get_check,  _get_read_data};static voidgtk_cups_result_set_error (GtkCupsResult    *result,                           GtkCupsErrorType  error_type,                           int               error_status,                           int               error_code,                            const char       *error_msg,			   ...){  va_list args;  result->is_ipp_response = FALSE;  result->is_error = TRUE;  result->error_type = error_type;  result->error_status = error_status;  result->error_code = error_code;  va_start (args, error_msg);  result->error_msg = g_strdup_vprintf (error_msg, args);  va_end (args);}GtkCupsRequest *gtk_cups_request_new (http_t             *connection,                      GtkCupsRequestType  req_type,                       gint                operation_id,                      GIOChannel         *data_io,                      const char         *server,                      const char         *resource){  GtkCupsRequest *request;  cups_lang_t *language;    request = g_new0 (GtkCupsRequest, 1);  request->result = g_new0 (GtkCupsResult, 1);  request->result->error_msg = NULL;  request->result->ipp_response = NULL;  request->result->is_error = FALSE;  request->result->is_ipp_response = FALSE;  request->type = req_type;  request->state = GTK_CUPS_REQUEST_START;   if (server)    request->server = g_strdup (server);  else    request->server = g_strdup (cupsServer ());  if (resource)    request->resource = g_strdup (resource);  else    request->resource = g_strdup ("/");   if (connection != NULL)    {      request->http = connection;      request->own_http = FALSE;    }  else    {      request->http = NULL;      request->http = httpConnectEncrypt (request->server,                                           ippPort (),                                           cupsEncryption ());      if (request->http)        httpBlocking (request->http, 0);              request->own_http = TRUE;    }  request->last_status = HTTP_CONTINUE;  request->attempts = 0;  request->data_io = data_io;  request->ipp_request = ippNew ();  request->ipp_request->request.op.operation_id = operation_id;  request->ipp_request->request.op.request_id = 1;  language = cupsLangDefault ();  gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,                                   "attributes-charset",                                    NULL, "utf-8");	  gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,                                   "attributes-natural-language",                                    NULL, language->language);  gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_NAME,                                   "requesting-user-name",                                   NULL, cupsUser ());    cupsLangFree (language);  return request;}static voidgtk_cups_result_free (GtkCupsResult *result){  g_free (result->error_msg);  if (result->ipp_response)    ippDelete (result->ipp_response);  g_free (result);}voidgtk_cups_request_free (GtkCupsRequest *request){  if (request->own_http)    {      if (request->http)        httpClose (request->http);    }    if (request->ipp_request)    ippDelete (request->ipp_request);  g_free (request->server);  g_free (request->resource);  gtk_cups_result_free (request->result);  g_free (request);}gboolean gtk_cups_request_read_write (GtkCupsRequest *request){  if (request->type == GTK_CUPS_POST)    post_states[request->state] (request);  else if (request->type == GTK_CUPS_GET)    get_states[request->state] (request);  if (request->attempts > _GTK_CUPS_MAX_ATTEMPTS &&       request->state != GTK_CUPS_REQUEST_DONE)    {      /* TODO: should add a status or error code for too many failed attempts */      gtk_cups_result_set_error (request->result,                                  GTK_CUPS_ERROR_GENERAL,                                 0,                                 0,                                  "Too many failed attempts");      request->state = GTK_CUPS_REQUEST_DONE;      request->poll_state = GTK_CUPS_HTTP_IDLE;    }      if (request->state == GTK_CUPS_REQUEST_DONE)    {      request->poll_state = GTK_CUPS_HTTP_IDLE;      return TRUE;    }  else    return FALSE;}GtkCupsPollState gtk_cups_request_get_poll_state (GtkCupsRequest *request){  return request->poll_state;}GtkCupsResult *gtk_cups_request_get_result (GtkCupsRequest *request){  return request->result;}void            gtk_cups_request_ipp_add_string (GtkCupsRequest *request,                                 ipp_tag_t       group,                                 ipp_tag_t       tag,                                 const char     *name,                                 const char     *charset,                                 const char     *value){  ippAddString (request->ipp_request,                group,                tag,                name,                charset,                value);}void            gtk_cups_request_ipp_add_strings (GtkCupsRequest    *request,				  ipp_tag_t          group,				  ipp_tag_t          tag,				  const char        *name,				  int                num_values,				  const char        *charset,				  const char *const *values){  ippAddStrings (request->ipp_request,		 group,		 tag,		 name,		 num_values,		 charset,		 values);}typedef struct{  const char	*name;  ipp_tag_t	value_tag;} ipp_option_t;static const ipp_option_t ipp_options[] = {  { "blackplot",		IPP_TAG_BOOLEAN },  { "brightness",		IPP_TAG_INTEGER },  { "columns",			IPP_TAG_INTEGER },  { "copies",			IPP_TAG_INTEGER },  { "finishings",		IPP_TAG_ENUM },  { "fitplot",			IPP_TAG_BOOLEAN },  { "gamma",			IPP_TAG_INTEGER },  { "hue",			IPP_TAG_INTEGER },  { "job-k-limit",		IPP_TAG_INTEGER },  { "job-page-limit",		IPP_TAG_INTEGER },  { "job-priority",		IPP_TAG_INTEGER },  { "job-quota-period",		IPP_TAG_INTEGER },  { "landscape",		IPP_TAG_BOOLEAN },  { "media",			IPP_TAG_KEYWORD },  { "mirror",			IPP_TAG_BOOLEAN },  { "natural-scaling",		IPP_TAG_INTEGER },  { "number-up",		IPP_TAG_INTEGER },  { "orientation-requested",	IPP_TAG_ENUM },  { "page-bottom",		IPP_TAG_INTEGER },  { "page-left",		IPP_TAG_INTEGER },  { "page-ranges",		IPP_TAG_RANGE },  { "page-right",		IPP_TAG_INTEGER },  { "page-top",			IPP_TAG_INTEGER },  { "penwidth",			IPP_TAG_INTEGER },  { "ppi",			IPP_TAG_INTEGER },  { "prettyprint",		IPP_TAG_BOOLEAN },  { "printer-resolution",	IPP_TAG_RESOLUTION },  { "print-quality",		IPP_TAG_ENUM },  { "saturation",		IPP_TAG_INTEGER },  { "scaling",			IPP_TAG_INTEGER },  { "sides",			IPP_TAG_KEYWORD },  { "wrap",			IPP_TAG_BOOLEAN }};static ipp_tag_t_find_option_tag (const gchar *option){  int lower_bound, upper_bound, num_options;  int current_option;  ipp_tag_t result;  result = IPP_TAG_ZERO;  lower_bound = 0;  upper_bound = num_options = (int) G_N_ELEMENTS (ipp_options) - 1;    while (1)    {      int match;      current_option = (int) (((upper_bound - lower_bound) / 2) + lower_bound);      match = strcasecmp (option, ipp_options[current_option].name);      if (match == 0)        {	  result = ipp_options[current_option].value_tag;	  return result;	}      else if (match < 0)        {          upper_bound = current_option - 1;	}      else        {          lower_bound = current_option + 1;	}      if (upper_bound == lower_bound && upper_bound == current_option)        return result;      if (upper_bound < 0)        return result;      if (lower_bound > num_options)        return result;      if (upper_bound < lower_bound)        return result;    }}/* * Note that this function uses IPP_TAG_JOB, so it is * only suitable for IPP Group 2 attributes. * See RFC 2911. */voidgtk_cups_request_encode_option (GtkCupsRequest *request,                                const gchar    *option,			        const gchar    *value){  ipp_tag_t option_tag;  g_return_if_fail (option != NULL);  g_return_if_fail (value != NULL);  option_tag = _find_option_tag (option);  if (option_tag == IPP_TAG_ZERO)    {      option_tag = IPP_TAG_NAME;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -