Esempio n. 1
0
GdkPixbuf *
_gtk_icon_cache_get_icon (GtkIconCache *cache,
			  const gchar  *icon_name,
			  gint          directory_index)
{
  guint32 offset, image_data_offset, pixel_data_offset;
  guint32 length, type;
  GdkPixbuf *pixbuf;
  GdkPixdata pixdata;
  GError *error = NULL;

  offset = find_image_offset (cache, icon_name, directory_index);
  
  image_data_offset = GET_UINT32 (cache->buffer, offset + 4);
  
  if (!image_data_offset)
    return NULL;

  pixel_data_offset = GET_UINT32 (cache->buffer, image_data_offset);

  type = GET_UINT32 (cache->buffer, pixel_data_offset);

  if (type != 0)
    {
      GTK_NOTE (ICONTHEME,
		g_print ("invalid pixel data type %u\n", type));
      return NULL;
    }

  length = GET_UINT32 (cache->buffer, pixel_data_offset + 4);
  
  if (!gdk_pixdata_deserialize (&pixdata, length, 
				(guchar *)(cache->buffer + pixel_data_offset + 8),
				&error))
    {
      GTK_NOTE (ICONTHEME,
		g_print ("could not deserialize data: %s\n", error->message));
      g_error_free (error);

      return NULL;
    }

  pixbuf = gdk_pixbuf_new_from_data (pixdata.pixel_data, GDK_COLORSPACE_RGB,
				     (pixdata.pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA,
				     8, pixdata.width, pixdata.height, pixdata.rowstride,
				     (GdkPixbufDestroyNotify)pixbuf_destroy_cb, 
				     cache);
  if (!pixbuf)
    {
      GTK_NOTE (ICONTHEME,
		g_print ("could not convert pixdata to pixbuf: %s\n", error->message));
      g_error_free (error);

      return NULL;
    }

  _gtk_icon_cache_ref (cache);

  return pixbuf;
}
Esempio n. 2
0
static void 
_get_read_data (GtkCupsRequest *request)
{
  char buffer[_GTK_CUPS_MAX_CHUNK_SIZE];
  gsize bytes;
  gsize bytes_written;
  GIOStatus io_status;
  GError *error;

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %s\n", G_STRFUNC));

  error = NULL;

  request->poll_state = GTK_CUPS_HTTP_READ;

#if HAVE_CUPS_API_1_2
  bytes = httpRead2 (request->http, buffer, sizeof (buffer));
#else
  bytes = httpRead (request->http, buffer, sizeof (buffer));
#endif /* HAVE_CUPS_API_1_2 */
  request->bytes_received += bytes;

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %" G_GSIZE_FORMAT " bytes read\n", bytes));
  
  io_status =
    g_io_channel_write_chars (request->data_io, 
                              buffer, 
			      bytes, 
			      &bytes_written,
			      &error);

  if (io_status == G_IO_STATUS_ERROR)
    {
      request->state = GTK_CUPS_GET_DONE;
      request->poll_state = GTK_CUPS_HTTP_IDLE;
    
      gtk_cups_result_set_error (request->result,
                                 GTK_CUPS_ERROR_IO,
                                 io_status,
                                 error->code, 
                                 error->message);
      g_error_free (error);
    }

  /* Stop if we do not expect any more data or EOF was received. */
#if HAVE_CUPS_API_1_2
  if (httpGetLength2 (request->http) <= request->bytes_received || bytes == 0)
#else
  if (httpGetLength (request->http) <= request->bytes_received || bytes == 0)
#endif /* HAVE_CUPS_API_1_2 */
    {
      request->state = GTK_CUPS_GET_DONE;
      request->poll_state = GTK_CUPS_HTTP_IDLE;

      return;
    }
}
Esempio n. 3
0
static void 
_get_read_data (GtkCupsRequest *request)
{
  char buffer[_GTK_CUPS_MAX_CHUNK_SIZE];
  gsize bytes;
  gsize bytes_written;
  GIOStatus io_status;
  GError *error;

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %s\n", G_STRFUNC));

  error = NULL;

  request->poll_state = GTK_CUPS_HTTP_READ;

#if HAVE_CUPS_API_1_2
  bytes = httpRead2 (request->http, buffer, sizeof (buffer));
#else
  bytes = httpRead (request->http, buffer, sizeof (buffer));
#endif /* HAVE_CUPS_API_1_2 */

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %i bytes read\n", bytes));
  
  if (bytes == 0)
    {
      request->state = GTK_CUPS_GET_DONE;
      request->poll_state = GTK_CUPS_HTTP_IDLE;

      return;
    }
  
  io_status =
    g_io_channel_write_chars (request->data_io, 
                              buffer, 
			      bytes, 
			      &bytes_written,
			      &error);

  if (io_status == G_IO_STATUS_ERROR)
    {
      request->state = GTK_CUPS_GET_DONE;
      request->poll_state = GTK_CUPS_HTTP_IDLE;
    
      gtk_cups_result_set_error (request->result,
                                 GTK_CUPS_ERROR_IO,
                                 io_status,
                                 error->code, 
                                 error->message);
      g_error_free (error);
    }
}
Esempio n. 4
0
static void 
_get_send (GtkCupsRequest *request)
{
  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %s\n", G_STRFUNC));

  request->poll_state = GTK_CUPS_HTTP_WRITE;

  if (request->data_io == NULL)
    {
      gtk_cups_result_set_error (request->result,
                                 GTK_CUPS_ERROR_IO,
                                 G_IO_STATUS_ERROR,
                                 G_IO_CHANNEL_ERROR_FAILED, 
                                 "Get requires an open io channel");

      request->state = GTK_CUPS_GET_DONE;
      request->poll_state = GTK_CUPS_HTTP_IDLE;

      return;
    }

  httpClearFields (request->http);
#ifdef HAVE_HTTPGETAUTHSTRING
  httpSetField (request->http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString (request->http));
#else
#ifdef HAVE_HTTP_AUTHSTRING
  httpSetField (request->http, HTTP_FIELD_AUTHORIZATION, request->http->authstring);
#endif
#endif

  if (httpGet (request->http, request->resource))
    {
      if (httpReconnect (request->http))
        {
          request->state = GTK_CUPS_GET_DONE;
          request->poll_state = GTK_CUPS_HTTP_IDLE;
	 
          /* TODO: should add a status or error code for failed GET */ 
          gtk_cups_result_set_error (request->result, 
                                     GTK_CUPS_ERROR_GENERAL,
                                     0,
                                     0,
                                     "Failed Get");
        }

      request->attempts++;
      return;    
    }

  if (httpCheck (request->http))
    request->last_status = httpUpdate (request->http);
        
  request->attempts = 0;

  request->state = GTK_CUPS_GET_CHECK;
  request->poll_state = GTK_CUPS_HTTP_READ;
  
  ippSetState (request->ipp_request, IPP_IDLE);
}
Esempio n. 5
0
static void 
_post_send (GtkCupsRequest *request)
{
  gchar length[255];
  struct stat data_info;

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %s\n", G_STRFUNC));

  request->poll_state = GTK_CUPS_HTTP_WRITE;

  if (request->data_io != NULL)
    {
      fstat (g_io_channel_unix_get_fd (request->data_io), &data_info);
      sprintf (length, "%lu", (unsigned long) (ippLength (request->ipp_request) + data_info.st_size));
    }
  else
    sprintf (length, "%lu", (unsigned long) ippLength (request->ipp_request));
	
  httpClearFields (request->http);
  httpSetField (request->http, HTTP_FIELD_CONTENT_LENGTH, length);
  httpSetField (request->http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
#ifdef HAVE_HTTPGETAUTHSTRING
  httpSetField (request->http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString (request->http));
#else
#ifdef HAVE_HTTP_AUTHSTRING
  httpSetField (request->http, HTTP_FIELD_AUTHORIZATION, request->http->authstring);
#endif
#endif

  if (httpPost (request->http, request->resource))
    {
      if (httpReconnect (request->http))
        {
          request->state = GTK_CUPS_POST_DONE;
          request->poll_state = GTK_CUPS_HTTP_IDLE;

          /* TODO: should add a status or error code for failed post */
          gtk_cups_result_set_error (request->result,
                                     GTK_CUPS_ERROR_GENERAL,
                                     0,
                                     0,
                                     "Failed Post");
        }

      request->attempts++;
      return;    
    }
        
    request->attempts = 0;

    request->state = GTK_CUPS_POST_WRITE_REQUEST;
    ippSetState (request->ipp_request, IPP_IDLE);
}
Esempio n. 6
0
void
gtk_icon_cache_unref (GtkIconCache *cache)
{
  cache->ref_count --;

  if (cache->ref_count == 0)
    {
      GTK_NOTE (ICONTHEME, g_message ("unmapping icon cache"));

      if (cache->map)
	g_mapped_file_unref (cache->map);
      g_free (cache);
    }
}
Esempio n. 7
0
static gboolean
gtk_theme_engine_load (GTypeModule *module)
{
  GtkThemeEngine *engine = GTK_THEME_ENGINE (module);
  
  gchar *engine_path;
      
  engine_path = gtk_rc_find_module_in_path (engine->name);
  
  if (!engine_path)
    {
      g_warning (_("Unable to locate theme engine in module_path: \"%s\","),
		 engine->name);
      return FALSE;
    }
    
  /* load the lib */
  
  GTK_NOTE (MISC, g_message ("Loading Theme %s\n", engine_path));
       
  engine->library = g_module_open (engine_path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
  g_free(engine_path);
  if (!engine->library)
    {
      g_warning (g_module_error());
      return FALSE;
    }
  
  /* extract symbols from the lib */
  if (!g_module_symbol (engine->library, "theme_init",
			(gpointer *)&engine->init) ||
      !g_module_symbol (engine->library, "theme_exit", 
			(gpointer *)&engine->exit) ||
      !g_module_symbol (engine->library, "theme_create_rc_style", 
			(gpointer *)&engine->create_rc_style))
    {
      g_warning (g_module_error());
      g_module_close (engine->library);
      
      return FALSE;
    }
	    
  /* call the theme's init (theme_init) function to let it */
  /* setup anything it needs to set up. */
  engine->init (module);

  return TRUE;
}
Esempio n. 8
0
static void 
_post_read_response (GtkCupsRequest *request)
{
  ipp_state_t ipp_status;

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %s\n", G_STRFUNC));

  request->poll_state = GTK_CUPS_HTTP_READ;

  if (request->result->ipp_response == NULL)
    request->result->ipp_response = ippNew();

  ipp_status = ippRead (request->http, 
                        request->result->ipp_response);

  if (ipp_status == IPP_ERROR)
    {
      int ipp_error = cupsLastError ();
      gtk_cups_result_set_error (request->result,  
                                 GTK_CUPS_ERROR_IPP,
                                 ipp_status,
                                 ipp_error,
                                 "%s",
                                 ippErrorString (ipp_error));
      
      ippDelete (request->result->ipp_response);
      request->result->ipp_response = NULL;

      request->state = GTK_CUPS_POST_DONE;
      request->poll_state = GTK_CUPS_HTTP_IDLE;
    }
  else if (ipp_status == IPP_DATA)
    {
      request->state = GTK_CUPS_POST_DONE;
      request->poll_state = GTK_CUPS_HTTP_IDLE;
    }
}
Esempio n. 9
0
static void 
_post_write_request (GtkCupsRequest *request)
{
  ipp_state_t ipp_status;

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %s\n", G_STRFUNC));

  request->poll_state = GTK_CUPS_HTTP_WRITE;
  
  ipp_status = ippWrite (request->http, request->ipp_request);

  if (ipp_status == IPP_ERROR)
    {
      int cups_error = cupsLastError ();
      request->state = GTK_CUPS_POST_DONE;
      request->poll_state = GTK_CUPS_HTTP_IDLE;
 
      gtk_cups_result_set_error (request->result, 
                                 GTK_CUPS_ERROR_IPP,
                                 ipp_status,
                                 cups_error,
                                 "%s", 
                                 ippErrorString (cups_error));
      return;
    }

  if (ipp_status == IPP_DATA)
    {
      if (request->data_io != NULL)
        request->state = GTK_CUPS_POST_WRITE_DATA;
      else
        {
          request->state = GTK_CUPS_POST_CHECK;
          request->poll_state = GTK_CUPS_HTTP_READ;
	}
    }
}
Esempio n. 10
0
/**
 * _gtk_xembed_send_message:
 * @recipient: (allow-none): window to which to send the window, or %NULL
 *             in which case nothing will be sent
 * @message:   type of message
 * @detail:    detail field of message
 * @data1:     data1 field of message
 * @data2:     data2 field of message
 * 
 * Sends a generic XEMBED message to a particular window.
 **/
void
_gtk_xembed_send_message (GdkWindow        *recipient,
			  XEmbedMessageType message,
			  glong             detail,
			  glong             data1,
			  glong             data2)
{
  GdkDisplay *display;
  XClientMessageEvent xclient;

  if (!recipient)
    return;
	  
  g_return_if_fail (GDK_IS_WINDOW (recipient));

  display = gdk_window_get_display (recipient);
  GTK_NOTE (PLUGSOCKET,
	    g_message ("Sending %s", _gtk_xembed_message_name (message)));

  memset (&xclient, 0, sizeof (xclient));
  xclient.window = GDK_WINDOW_XID (recipient);
  xclient.type = ClientMessage;
  xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED");
  xclient.format = 32;
  xclient.data.l[0] = gtk_xembed_get_time ();
  xclient.data.l[1] = message;
  xclient.data.l[2] = detail;
  xclient.data.l[3] = data1;
  xclient.data.l[4] = data2;

  gdk_x11_display_error_trap_push (display);
  XSendEvent (GDK_WINDOW_XDISPLAY(recipient),
	      GDK_WINDOW_XID (recipient),
	      False, NoEventMask, (XEvent *)&xclient);
  gdk_x11_display_error_trap_pop_ignored (display);
}
Esempio n. 11
0
static void 
_post_write_data (GtkCupsRequest *request)
{
  gsize bytes;
  char buffer[_GTK_CUPS_MAX_CHUNK_SIZE];
  http_status_t http_status;

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %s\n", G_STRFUNC));

  request->poll_state = GTK_CUPS_HTTP_WRITE;
  
  if (httpCheck (request->http))
    http_status = httpUpdate (request->http);
  else
    http_status = request->last_status;

  request->last_status = http_status;


  if (http_status == HTTP_CONTINUE || http_status == HTTP_OK)
    {
      GIOStatus io_status;
      GError *error;

      error = NULL;

      /* send data */
      io_status =
        g_io_channel_read_chars (request->data_io, 
	                         buffer, 
				 _GTK_CUPS_MAX_CHUNK_SIZE,
				 &bytes,
				 &error);

      if (io_status == G_IO_STATUS_ERROR)
        {
          request->state = GTK_CUPS_POST_DONE;
	  request->poll_state = GTK_CUPS_HTTP_IDLE;
     
          gtk_cups_result_set_error (request->result,
                                     GTK_CUPS_ERROR_IO,
                                     io_status,
                                     error->code, 
                                     "Error reading from cache file: %s",
                                     error->message);

	  g_error_free (error);
          return;
	}
      else if (bytes == 0 && io_status == G_IO_STATUS_EOF)
        {
          request->state = GTK_CUPS_POST_CHECK;
	  request->poll_state = GTK_CUPS_HTTP_READ;

          request->attempts = 0;
          return;
        }


      if (httpWrite2 (request->http, buffer, bytes) < bytes)
        {
          int http_errno;

          http_errno = httpError (request->http);

          request->state = GTK_CUPS_POST_DONE;
	  request->poll_state = GTK_CUPS_HTTP_IDLE;
     
          gtk_cups_result_set_error (request->result,
                                     GTK_CUPS_ERROR_HTTP,
                                     http_status,
                                     http_errno, 
                                     "Error writing to socket in Post %s", 
                                     g_strerror (http_errno));
          return;
        }
    }
  else if (http_status == HTTP_UNAUTHORIZED)
    {
      request->state = GTK_CUPS_POST_CHECK;
      request->poll_state = GTK_CUPS_HTTP_READ;

      request->attempts = 0;
      return;
    }
  else
    {
      request->attempts++;
    }
}
Esempio n. 12
0
GtkIconCache *
gtk_icon_cache_new_for_path (const gchar *path)
{
  GtkIconCache *cache = NULL;
  GMappedFile *map;

  gchar *cache_filename;
  gint fd = -1;
  GStatBuf st;
  GStatBuf path_st;

   /* Check if we have a cache file */
  cache_filename = g_build_filename (path, "icon-theme.cache", NULL);

  GTK_NOTE (ICONTHEME, g_message ("look for icon cache in %s", path));

  if (g_stat (path, &path_st) < 0)
    goto done;

  /* Open the file and map it into memory */
  fd = g_open (cache_filename, O_RDONLY|_O_BINARY, 0);

  if (fd < 0)
    goto done;

#ifdef G_OS_WIN32

/* Bug 660730: _fstat32 is only defined in msvcrt80.dll+/VS 2005+ */
/*             or possibly in the msvcrt.dll linked to by the Windows DDK */
/*             (will need to check on the Windows DDK part later) */
#if ((defined (_MSC_VER) && (_MSC_VER >= 1400 || __MSVCRT_VERSION__ >= 0x0800)) || defined (__MINGW64_VERSION_MAJOR)) && !defined(_WIN64)
#undef fstat /* Just in case */
#define fstat _fstat32  
#endif
#endif

  if (fstat (fd, &st) < 0 || st.st_size < 4)
    goto done;

  /* Verify cache is uptodate */
  if (st.st_mtime < path_st.st_mtime)
    {
      GTK_NOTE (ICONTHEME, g_message ("icon cache outdated"));
      goto done; 
    }

  map = g_mapped_file_new (cache_filename, FALSE, NULL);

  if (!map)
    goto done;

#ifdef G_ENABLE_DEBUG
  if (GTK_DEBUG_CHECK (ICONTHEME))
    {
      CacheInfo info;

      info.cache = g_mapped_file_get_contents (map);
      info.cache_size = g_mapped_file_get_length (map);
      info.n_directories = 0;
      info.flags = CHECK_OFFSETS|CHECK_STRINGS;

      if (!gtk_icon_cache_validate (&info))
        {
          g_mapped_file_unref (map);
          g_warning ("Icon cache '%s' is invalid", cache_filename);

          goto done;
        }
    }
#endif 

  GTK_NOTE (ICONTHEME, g_message ("found icon cache for %s", path));

  cache = g_new0 (GtkIconCache, 1);
  cache->ref_count = 1;
  cache->map = map;
  cache->buffer = g_mapped_file_get_contents (map);

 done:
  g_free (cache_filename);  
  if (fd >= 0)
    close (fd);

  return cache;
}
Esempio n. 13
0
GtkIconCache *
_gtk_icon_cache_new_for_path (const gchar *path)
{
  GtkIconCache *cache = NULL;
  GMappedFile *map;

  gchar *cache_filename;
  gint fd = -1;
  struct stat st;
  struct stat path_st;
  CacheInfo info;

   /* Check if we have a cache file */
  cache_filename = g_build_filename (path, "icon-theme.cache", NULL);

  GTK_NOTE (ICONTHEME, 
	    g_print ("look for cache in %s\n", path));

  if (g_stat (path, &path_st) < 0)
    goto done;

  /* Open the file and map it into memory */
  fd = g_open (cache_filename, O_RDONLY|_O_BINARY, 0);

  if (fd < 0)
    goto done;
  
  if (fstat (fd, &st) < 0 || st.st_size < 4)
    goto done;

  /* Verify cache is uptodate */
  if (st.st_mtime < path_st.st_mtime)
    {
      GTK_NOTE (ICONTHEME, 
		g_print ("cache outdated\n"));
      goto done; 
    }

  map = g_mapped_file_new (cache_filename, FALSE, NULL);

  if (!map)
    goto done;

  info.cache = g_mapped_file_get_contents (map);
  info.cache_size = g_mapped_file_get_length (map);
  info.n_directories = 0;
  info.flags = CHECK_OFFSETS|CHECK_STRINGS;

#ifdef G_ENABLE_DEBUG
  if (gtk_debug_flags & GTK_DEBUG_ICONTHEME)
    {
      if (!_gtk_icon_cache_validate (&info))
        {
          g_mapped_file_free (map);
          g_warning ("Icon cache '%s' is invalid\n", cache_filename);

          goto done;
        }
    }
#endif 

  GTK_NOTE (ICONTHEME, g_print ("found cache for %s\n", path));

  cache = g_new0 (GtkIconCache, 1);
  cache->ref_count = 1;
  cache->map = map;
  cache->buffer = g_mapped_file_get_contents (map);

 done:
  g_free (cache_filename);  
  if (fd >= 0)
    close (fd);

  return cache;
}
Esempio n. 14
0
/**
 * _gtk_key_hash_lookup:
 * @key_hash: a #GtkKeyHash
 * @hardware_keycode: hardware keycode field from a #GdkEventKey
 * @state: state field from a #GdkEventKey
 * @mask: mask of modifiers to consider when matching against the
 *        modifiers in entries.
 * @group: group field from a #GdkEventKey
 * 
 * Looks up the best matching entry or entries in the hash table for
 * a given event. The results are sorted so that entries with less
 * modifiers come before entries with more modifiers.
 * 
 * The matches returned by this function can be exact (i.e. keycode, level
 * and group all match) or fuzzy (i.e. keycode and level match, but group
 * does not). As long there are any exact matches, only exact matches
 * are returned. If there are no exact matches, fuzzy matches will be
 * returned, as long as they are not shadowing a possible exact match.
 * This means that fuzzy matches won’t be considered if their keyval is 
 * present in the current group.
 * 
 * Return value: A newly-allocated #GSList of matching entries.
 *     Free with g_slist_free() when no longer needed.
 */
GSList *
_gtk_key_hash_lookup (GtkKeyHash      *key_hash,
		      guint16          hardware_keycode,
		      GdkModifierType  state,
		      GdkModifierType  mask,
		      gint             group)
{
  GHashTable *keycode_hash = key_hash_get_keycode_hash (key_hash);
  GSList *keys = g_hash_table_lookup (keycode_hash, GUINT_TO_POINTER ((guint)hardware_keycode));
  GSList *results = NULL;
  GSList *l;
  gboolean have_exact = FALSE;
  guint keyval;
  gint effective_group;
  gint level;
  GdkModifierType modifiers;
  GdkModifierType consumed_modifiers;
  GdkModifierType shift_group_mask;
  gboolean group_mod_is_accel_mod = FALSE;
  const GdkModifierType xmods = GDK_MOD2_MASK|GDK_MOD3_MASK|GDK_MOD4_MASK|GDK_MOD5_MASK;
  const GdkModifierType vmods = GDK_SUPER_MASK|GDK_HYPER_MASK|GDK_META_MASK;

  /* We don't want Caps_Lock to affect keybinding lookups.
   */
  state &= ~GDK_LOCK_MASK;

  _gtk_translate_keyboard_accel_state (key_hash->keymap,
                                       hardware_keycode, state, mask, group,
                                       &keyval,
                                       &effective_group, &level, &consumed_modifiers);

  /* if the group-toggling modifier is part of the default accel mod
   * mask, and it is active, disable it for matching
   */
  shift_group_mask = gdk_keymap_get_modifier_mask (key_hash->keymap,
                                                   GDK_MODIFIER_INTENT_SHIFT_GROUP);
  if (mask & shift_group_mask)
    group_mod_is_accel_mod = TRUE;

  gdk_keymap_map_virtual_modifiers (key_hash->keymap, &mask);
  gdk_keymap_add_virtual_modifiers (key_hash->keymap, &state);

  GTK_NOTE (KEYBINDINGS,
	    g_message ("Looking up keycode = %u, modifiers = 0x%04x,\n"
		       "    keyval = %u, group = %d, level = %d, consumed_modifiers = 0x%04x",
		       hardware_keycode, state, keyval, effective_group, level, consumed_modifiers));

  if (keys)
    {
      GSList *tmp_list = keys;
      while (tmp_list)
	{
	  GtkKeyHashEntry *entry = tmp_list->data;

	  /* If the virtual Super, Hyper or Meta modifiers are present,
	   * they will also be mapped to some of the Mod2 - Mod5 modifiers,
	   * so we compare them twice, ignoring either set.
	   * We accept combinations involving virtual modifiers only if they
	   * are mapped to separate modifiers; i.e. if Super and Hyper are
	   * both mapped to Mod4, then pressing a key that is mapped to Mod4
	   * will not match a Super+Hyper entry.
	   */
          modifiers = entry->modifiers;
          if (gdk_keymap_map_virtual_modifiers (key_hash->keymap, &modifiers) &&
	      ((modifiers & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) ||
	       (modifiers & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods)))
	    {
	      gint i;

	      if (keyval == entry->keyval && /* Exact match */
                  /* but also match for group if it is an accel mod, because
                   * otherwise we can get multiple exact matches, some being
                   * bogus */
                  (!group_mod_is_accel_mod ||
                   (state & shift_group_mask) == (entry->modifiers & shift_group_mask)))

		{
		  GTK_NOTE (KEYBINDINGS,
			    g_message ("  found exact match, keyval = %u, modifiers = 0x%04x",
				       entry->keyval, entry->modifiers));

		  if (!have_exact)
		    {
		      g_slist_free (results);
		      results = NULL;
		    }

		  have_exact = TRUE;
		  results = g_slist_prepend (results, entry);
		}

	      if (!have_exact)
		{
		  for (i = 0; i < entry->n_keys; i++)
		    {
                      if (entry->keys[i].keycode == hardware_keycode &&
                          entry->keys[i].level == level &&
                           /* Only match for group if it's an accel mod */
                          (!group_mod_is_accel_mod ||
                           entry->keys[i].group == effective_group))
			{
			  GTK_NOTE (KEYBINDINGS,
				    g_message ("  found group = %d, level = %d",
					       entry->keys[i].group, entry->keys[i].level));
			  results = g_slist_prepend (results, entry);
			  break;
			}
		    }
		}
	    }

	  tmp_list = tmp_list->next;
	}
    }

  if (!have_exact && results) 
    {
      /* If there are fuzzy matches, check that the current group doesn't also 
       * define these keyvals; if yes, discard results because a widget up in 
       * the stack may have an exact match and we don't want to 'steal' it.
       */
      guint oldkeyval = 0;
      GtkKeyHashEntry *keyhashentry;

      results = sort_lookup_results_by_keyval (results);
      for (l = results; l; l = l->next)
        {
          keyhashentry = l->data;
          if (l == results || oldkeyval != keyhashentry->keyval)
            {
              oldkeyval = keyhashentry->keyval;
              if (keyval_in_group (key_hash->keymap, oldkeyval, group))
                {
       	          g_slist_free (results);
       	          return NULL;
                }
            }
        }
    }
    
  results = sort_lookup_results (results);
  for (l = results; l; l = l->next)
    l->data = ((GtkKeyHashEntry *)l->data)->value;

  return results;
}
Esempio n. 15
0
static GdkPixbuf *
render_icon (GtkStyle               *style,
	     const GtkIconSource    *source,
	     GtkTextDirection        direction,
	     GtkStateType            state,
	     GtkIconSize             size,
	     GtkWidget              *widget,
	     const gchar            *detail)
{
	int width = 1;
	int height = 1;
	GdkPixbuf *scaled;
	GdkPixbuf *stated;
	GdkPixbuf *base_pixbuf;
	GdkScreen *screen;
	GtkSettings *settings;

	/* Oddly, style can be NULL in this function, because
	 * GtkIconSet can be used without a style and if so
	 * it uses this function.
	 */

	base_pixbuf = gtk_icon_source_get_pixbuf (source);

	g_return_val_if_fail (base_pixbuf != NULL, NULL);

	if (widget && gtk_widget_has_screen (widget))
	{
		screen = gtk_widget_get_screen (widget);
		settings = gtk_settings_get_for_screen (screen);
	}
	else if (style->colormap)
	{
		screen = gdk_colormap_get_screen (style->colormap);
		settings = gtk_settings_get_for_screen (screen);
	}
	else
	{
		settings = gtk_settings_get_default ();
		GTK_NOTE (MULTIHEAD,
			  g_warning ("Using the default screen for gtk_default_render_icon()"));
	}

	if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height))
	{
		g_warning (G_STRLOC ": invalid icon size '%d'", size);
		return NULL;
	}

	/* If the size was wildcarded, and we're allowed to scale, then scale; otherwise,
	 * leave it alone.
	 */
	if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source))
		scaled = scale_or_ref (base_pixbuf, width, height);
	else
		scaled = g_object_ref (base_pixbuf);

	/* If the state was wildcarded, then generate a state. */
	if (gtk_icon_source_get_state_wildcarded (source))
	{
		if (state == GTK_STATE_INSENSITIVE)
		{
			stated = set_transparency (scaled, 0.3);
			gdk_pixbuf_saturate_and_pixelate (stated, stated, 0.1, FALSE);

			g_object_unref (scaled);
		}
		else if (state == GTK_STATE_PRELIGHT)
		{
			stated = gdk_pixbuf_copy (scaled);

			gdk_pixbuf_saturate_and_pixelate (scaled, stated, 1.2, FALSE);

			g_object_unref (scaled);
		}
		else
		{
			stated = scaled;
		}
	}
	else
		stated = scaled;

	return stated;
}
Esempio n. 16
0
/**
 * _gtk_key_hash_lookup:
 * @key_hash: a #GtkKeyHash
 * @hardware_keycode: hardware keycode field from a #GdkEventKey
 * @state: state field from a #GdkEventKey
 * @mask: mask of modifiers to consider when matching against the
 *        modifiers in entries.
 * @group: group field from a #GdkEventKey
 *
 * Looks up the best matching entry or entries in the hash table for
 * a given event. The results are sorted so that entries with less
 * modifiers come before entries with more modifiers.
 *
 * Return value: A #GSList of all matching entries. If there were exact
 *  matches, they are returned, otherwise all fuzzy matches are
 *  returned. (A fuzzy match is a match in keycode and level, but not
 *  in group.)
 **/
GSList *
_gtk_key_hash_lookup (GtkKeyHash      *key_hash,
                      guint16          hardware_keycode,
                      GdkModifierType  state,
                      GdkModifierType  mask,
                      gint             group)
{
    GHashTable *keycode_hash = key_hash_get_keycode_hash (key_hash);
    GSList *keys = g_hash_table_lookup (keycode_hash, GUINT_TO_POINTER ((guint)hardware_keycode));
    GSList *results = NULL;
    GSList *l;
    gboolean have_exact = FALSE;
    guint keyval;
    gint effective_group;
    gint level;
    GdkModifierType consumed_modifiers;

    /* We don't want Caps_Lock to affect keybinding lookups.
     */
    state &= ~GDK_LOCK_MASK;

    gdk_keymap_translate_keyboard_state (key_hash->keymap,
                                         hardware_keycode, state, group,
                                         &keyval, &effective_group, &level, &consumed_modifiers);

    GTK_NOTE (KEYBINDINGS,
              g_message ("Looking up keycode = %u, modifiers = 0x%04x,\n"
                         "    keyval = %u, group = %d, level = %d, consumed_modifiers = 0x%04x",
                         hardware_keycode, state, keyval, effective_group, level, consumed_modifiers));

    if (keys)
    {
        GSList *tmp_list = keys;
        while (tmp_list)
        {
            GtkKeyHashEntry *entry = tmp_list->data;
            GdkModifierType xmods, vmods;

            /* If the virtual super, hyper or meta modifiers are present,
             * they will also be mapped to some of the mod2 - mod5 modifiers,
             * so we compare them twice, ignoring either set.
             */
            xmods = GDK_MOD2_MASK|GDK_MOD3_MASK|GDK_MOD4_MASK|GDK_MOD5_MASK;
            vmods = GDK_SUPER_MASK|GDK_HYPER_MASK|GDK_META_MASK;

            if ((entry->modifiers & ~consumed_modifiers & mask & ~vmods) == (state & ~consumed_modifiers & mask & ~vmods) ||
                    (entry->modifiers & ~consumed_modifiers & mask & ~xmods) == (state & ~consumed_modifiers & mask & ~xmods))
            {
                gint i;

                if (keyval == entry->keyval) /* Exact match */
                {
                    GTK_NOTE (KEYBINDINGS,
                              g_message ("  found exact match, keyval = %u, modifiers = 0x%04x",
                                         entry->keyval, entry->modifiers));

                    if (!have_exact)
                    {
                        g_slist_free (results);
                        results = NULL;
                    }

                    have_exact = TRUE;
                    results = g_slist_prepend (results, entry);
                }

                if (!have_exact)
                {
                    for (i = 0; i < entry->n_keys; i++)
                    {
                        if (entry->keys[i].keycode == hardware_keycode &&
                                entry->keys[i].level == level) /* Match for all but group */
                        {
                            GTK_NOTE (KEYBINDINGS,
                                      g_message ("  found group = %d, level = %d",
                                                 entry->keys[i].group, entry->keys[i].level));
                            results = g_slist_prepend (results, entry);
                            break;
                        }
                    }
                }
            }

            tmp_list = tmp_list->next;
        }
    }

    results = sort_lookup_results (results);
    for (l = results; l; l = l->next)
        l->data = ((GtkKeyHashEntry *)l->data)->value;

    return results;
}
Esempio n. 17
0
static void 
_post_check (GtkCupsRequest *request)
{
  http_status_t http_status;

  http_status = request->last_status;

  GTK_NOTE (PRINTING,
            g_print ("CUPS Backend: %s - status %i\n", G_STRFUNC, http_status));

  request->poll_state = GTK_CUPS_HTTP_READ;

  if (http_status == HTTP_CONTINUE)
    {
      goto again; 
    }
  else if (http_status == HTTP_UNAUTHORIZED)
    {
      int auth_result = -1;
      httpFlush (request->http);

      if (request->password_state == GTK_CUPS_PASSWORD_APPLIED)
        {
          request->poll_state = GTK_CUPS_HTTP_IDLE;
          request->password_state = GTK_CUPS_PASSWORD_NOT_VALID;
          request->state = GTK_CUPS_POST_AUTH;
          request->need_password = TRUE;

          return;
        }

      /* Negotiate */
      if (strncmp (httpGetField (request->http, HTTP_FIELD_WWW_AUTHENTICATE), "Negotiate", 9) == 0)
        {
          auth_result = cupsDoAuthentication (request->http, "POST", request->resource);
        }
      /* Basic, BasicDigest, Digest and PeerCred */
      else
        {
          if (request->password_state == GTK_CUPS_PASSWORD_NONE)
            {
              cups_username = request->username;
              cupsSetPasswordCB (passwordCB);

              /* This call success for PeerCred authentication */
              auth_result = cupsDoAuthentication (request->http, "POST", request->resource);

              if (auth_result != 0)
                {
                  /* move to AUTH state to let the backend 
                   * ask for a password
                   */ 
                  request->poll_state = GTK_CUPS_HTTP_IDLE;
                  request->state = GTK_CUPS_POST_AUTH;
                  request->need_password = TRUE;

                  return;
                }
            }
          else
            {
              cups_password = request->password;
              cups_username = request->username;

              auth_result = cupsDoAuthentication (request->http, "POST", request->resource);

              if (cups_password != NULL)
                return;

              if (request->password != NULL)
                {
                  memset (request->password, 0, strlen (request->password));
                  g_free (request->password);
                  request->password = NULL;
                }

              request->password_state = GTK_CUPS_PASSWORD_APPLIED;
            }
        }

      if (auth_result ||
          httpReconnect (request->http))
        {
          /* if the password has been used, reset password_state
           * so that we ask for a new one next time around
           */ 
          if (cups_password == NULL)
            request->password_state = GTK_CUPS_PASSWORD_NONE;

          request->state = GTK_CUPS_POST_DONE;
          request->poll_state = GTK_CUPS_HTTP_IDLE;
          gtk_cups_result_set_error (request->result, 
                                     GTK_CUPS_ERROR_AUTH,
                                     0,
                                     0,
                                     "Not authorized");
          return;
        }
      
      if (request->data_io != NULL)
        g_io_channel_seek_position (request->data_io, 0, G_SEEK_SET, NULL);

      request->state = GTK_CUPS_POST_CONNECT;
      request->poll_state = GTK_CUPS_HTTP_WRITE;
    }
  else if (http_status == HTTP_ERROR)
    {
      int error = httpError (request->http);
#ifdef G_OS_WIN32
      if (error != WSAENETDOWN && error != WSAENETUNREACH)
#else
      if (error != ENETDOWN && error != ENETUNREACH)	  
#endif /* G_OS_WIN32 */
        {
          request->attempts++;
          goto again;
        }
      else
        {
          request->state = GTK_CUPS_POST_DONE;
          request->poll_state = GTK_CUPS_HTTP_IDLE;
     
          gtk_cups_result_set_error (request->result,
                                     GTK_CUPS_ERROR_HTTP,
                                     http_status,
                                     error, 
                                     "Unknown HTTP error");

          return;
        }
    }
  else if (http_status == HTTP_UPGRADE_REQUIRED)
    {
      /* Flush any error message... */
      httpFlush (request->http);

      cupsSetEncryption (HTTP_ENCRYPT_REQUIRED);
      request->state = GTK_CUPS_POST_CONNECT;

      /* Reconnect... */
      httpReconnect (request->http);

      /* Upgrade with encryption... */
      httpEncryption (request->http, HTTP_ENCRYPT_REQUIRED);
 
      request->attempts++;
      goto again;
    }
  else if (http_status != HTTP_OK)
    {
      int http_errno;

      http_errno = httpError (request->http);

      if (http_errno == EPIPE)
        request->state = GTK_CUPS_POST_CONNECT;
      else
        {
          request->state = GTK_CUPS_POST_DONE;
          gtk_cups_result_set_error (request->result,
                                     GTK_CUPS_ERROR_HTTP,
                                     http_status,
                                     http_errno, 
                                     "HTTP Error in POST %s", 
                                     g_strerror (http_errno));
          request->poll_state = GTK_CUPS_HTTP_IDLE;
 
          httpFlush (request->http); 
          return;
        }

      request->poll_state = GTK_CUPS_HTTP_IDLE;
      request->last_status = HTTP_CONTINUE;

      httpFlush (request->http);
      if (request->own_http)
        httpClose (request->http);
      request->http = NULL;

      return;
    }
  else
    {
      request->state = GTK_CUPS_POST_READ_RESPONSE;
      return;
    }

 again:
  http_status = HTTP_CONTINUE;

  if (httpCheck (request->http))
    http_status = httpUpdate (request->http);

  request->last_status = http_status;
}
Esempio n. 18
0
static void
parse_object (GMarkupParseContext  *context,
              ParserData           *data,
              const gchar          *element_name,
              const gchar         **names,
              const gchar         **values,
              GError              **error)
{
  ObjectInfo *object_info;
  ChildInfo* child_info;
  GType object_type = G_TYPE_INVALID;
  const gchar *object_class = NULL;
  const gchar *constructor = NULL;
  const gchar *type_func = NULL;
  const gchar *object_id = NULL;
  gchar *internal_id = NULL;
  gint line;

  child_info = state_peek_info (data, ChildInfo);
  if (child_info && strcmp (child_info->tag.name, "object") == 0)
    {
      error_invalid_tag (data, element_name, NULL, error);
      return;
    }

  if (!g_markup_collect_attributes (element_name, names, values, error,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "class", &object_class,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "constructor", &constructor,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "type-func", &type_func,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "id", &object_id,
                                    G_MARKUP_COLLECT_INVALID))
    {
      _gtk_builder_prefix_error (data->builder, data->ctx, error);
      return;
    }

  if (type_func)
    {
      /* Call the GType function, and return the GType, it's guaranteed afterwards
       * that g_type_from_name on the name will return our GType
       */
      object_type = _get_type_by_symbol (type_func);
      if (object_type == G_TYPE_INVALID)
        {
          g_set_error (error,
                       GTK_BUILDER_ERROR,
                       GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION,
                       "Invalid type function '%s'", type_func);
          _gtk_builder_prefix_error (data->builder, context, error);
          return;
        }
    }
  else if (object_class)
    {
      object_type = gtk_builder_get_type_from_name (data->builder, object_class);
      if (object_type == G_TYPE_INVALID)
        {
          g_set_error (error,
                       GTK_BUILDER_ERROR,
                       GTK_BUILDER_ERROR_INVALID_VALUE,
                       "Invalid object type '%s'", object_class);
          _gtk_builder_prefix_error (data->builder, context, error);
          return;
       }
    }
  else
    {
      error_missing_attribute (data, element_name, "class", error);
      return;
    }

  if (!object_id)
    {
      internal_id = g_strdup_printf ("___object_%d___", ++data->object_counter);
      object_id = internal_id;
    }

  ++data->cur_object_level;

  /* check if we reached a requested object (if it is specified) */
  if (data->requested_objects && !data->inside_requested_object)
    {
      if (is_requested_object (object_id, data))
        {
          data->requested_object_level = data->cur_object_level;

          GTK_NOTE (BUILDER,
                    g_message ("requested object \"%s\" found at level %d",
                               object_id, data->requested_object_level));

          data->inside_requested_object = TRUE;
        }
      else
        {
          g_free (internal_id);
          return;
        }
    }

  object_info = g_slice_new0 (ObjectInfo);
  object_info->tag.name = element_name;
  object_info->type = object_type;
  object_info->oclass = g_type_class_ref (object_type);
  object_info->id = (internal_id) ? internal_id : g_strdup (object_id);
  object_info->constructor = g_strdup (constructor);
  object_info->parent = (CommonInfo*)child_info;
  state_push (data, object_info);

  line = GPOINTER_TO_INT (g_hash_table_lookup (data->object_ids, object_id));
  if (line != 0)
    {
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_DUPLICATE_ID,
                   "Duplicate object ID '%s' (previously on line %d)",
                   object_id, line);
      _gtk_builder_prefix_error (data->builder, context, error);
      return;
    }

  g_markup_parse_context_get_position (context, &line, NULL);
  g_hash_table_insert (data->object_ids, g_strdup (object_id), GINT_TO_POINTER (line));
}
Esempio n. 19
0
static void
end_element (GMarkupParseContext  *context,
             const gchar          *element_name,
             gpointer              user_data,
             GError              **error)
{
  ParserData *data = (ParserData*)user_data;

  GTK_NOTE (BUILDER, g_message ("</%s>", element_name));

  if (data->subparser && data->subparser->start)
    {
      subparser_end (context, element_name, data, error);
      return;
    }

  if (strcmp (element_name, "requires") == 0)
    {
      RequiresInfo *req_info = state_pop_info (data, RequiresInfo);

      /* TODO: Allow third party widget developers to check thier
       * required versions, possibly throw a signal allowing them
       * to check thier library versions here.
       */
      if (!strcmp (req_info->library, "gtk+"))
        {
          if (!GTK_CHECK_VERSION (req_info->major, req_info->minor, 0))
            {
              g_set_error (error,
                           GTK_BUILDER_ERROR,
                           GTK_BUILDER_ERROR_VERSION_MISMATCH,
                           "Required %s version %d.%d, current version is %d.%d",
                           req_info->library,
                           req_info->major, req_info->minor,
                           GTK_MAJOR_VERSION, GTK_MINOR_VERSION);
              _gtk_builder_prefix_error (data->builder, context, error);
           }
        }
      free_requires_info (req_info, NULL);
    }
  else if (strcmp (element_name, "interface") == 0)
    {
    }
  else if (data->requested_objects && !data->inside_requested_object)
    {
      /* If outside a requested object, simply ignore this tag */
    }
  else if (strcmp (element_name, "menu") == 0)
    {
      _gtk_builder_menu_end (data);
    }
  else if (strcmp (element_name, "object") == 0 ||
           strcmp (element_name, "template") == 0)
    {
      ObjectInfo *object_info = state_pop_info (data, ObjectInfo);
      ChildInfo* child_info = state_peek_info (data, ChildInfo);

      if (data->requested_objects && data->inside_requested_object &&
          (data->cur_object_level == data->requested_object_level))
        {
          GTK_NOTE (BUILDER,
                    g_message ("requested object end found at level %d",
                               data->requested_object_level));

          data->inside_requested_object = FALSE;
        }

      --data->cur_object_level;

      g_assert (data->cur_object_level >= 0);

      object_info->object = builder_construct (data, object_info, error);
      if (!object_info->object)
        {
          free_object_info (object_info);
          return;
        }
      if (child_info)
        child_info->object = object_info->object;

      if (GTK_IS_BUILDABLE (object_info->object) &&
          GTK_BUILDABLE_GET_IFACE (object_info->object)->parser_finished)
        data->finalizers = g_slist_prepend (data->finalizers, object_info->object);
      _gtk_builder_add_signals (data->builder, object_info->signals);

      free_object_info (object_info);
    }
  else if (strcmp (element_name, "property") == 0)
    {
      PropertyInfo *prop_info = state_pop_info (data, PropertyInfo);
      CommonInfo *info = state_peek_info (data, CommonInfo);

      g_assert (info != NULL);

      /* Normal properties */
      if (strcmp (info->tag.name, "object") == 0 ||
          strcmp (info->tag.name, "template") == 0)
        {
          ObjectInfo *object_info = (ObjectInfo*)info;

          if (prop_info->translatable && prop_info->text->len)
            {
              const gchar *translated;

              translated = _gtk_builder_parser_translate (data->domain,
                                                          prop_info->context,
                                                          prop_info->text->str);
              g_string_assign (prop_info->text, translated);
            }

          object_info->properties = g_slist_prepend (object_info->properties, prop_info);
        }
      else
        g_assert_not_reached ();
    }
  else if (strcmp (element_name, "child") == 0)
    {
      ChildInfo *child_info = state_pop_info (data, ChildInfo);

      _gtk_builder_add (data->builder, child_info);

      free_child_info (child_info);
    }
  else if (strcmp (element_name, "signal") == 0)
    {
      SignalInfo *signal_info = state_pop_info (data, SignalInfo);
      ObjectInfo *object_info = (ObjectInfo*)state_peek_info (data, CommonInfo);
      g_assert (object_info != NULL);
      signal_info->object_name = g_strdup (object_info->id);
      object_info->signals = g_slist_prepend (object_info->signals, signal_info);
    }
  else if (strcmp (element_name, "placeholder") == 0)
    {
    }
  else
    {
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_UNHANDLED_TAG,
                   "Unhandled tag: <%s>", element_name);
      _gtk_builder_prefix_error (data->builder, context, error);
    }
}
Esempio n. 20
0
static void
parse_object (GMarkupParseContext  *context,
              ParserData           *data,
              const gchar          *element_name,
              const gchar         **names,
              const gchar         **values,
              GError              **error)
{
  ObjectInfo *object_info;
  ChildInfo* child_info;
  int i;
  gchar *object_class = NULL;
  gchar *object_id = NULL;
  gchar *constructor = NULL;
  gint line, line2;

  child_info = state_peek_info (data, ChildInfo);
  if (child_info && strcmp (child_info->tag.name, "object") == 0)
    {
      error_invalid_tag (data, element_name, NULL, error);
      return;
    }

  for (i = 0; names[i] != NULL; i++)
    {
      if (strcmp (names[i], "class") == 0)
        object_class = g_strdup (values[i]);
      else if (strcmp (names[i], "id") == 0)
        object_id = g_strdup (values[i]);
      else if (strcmp (names[i], "constructor") == 0)
        constructor = g_strdup (values[i]);
      else if (strcmp (names[i], "type-func") == 0)
        {
	  /* Call the GType function, and return the name of the GType,
	   * it's guaranteed afterwards that g_type_from_name on the name
	   * will return our GType
	   */
          object_class = _get_type_by_symbol (values[i]);
          if (!object_class)
            {
              g_markup_parse_context_get_position (context, &line, NULL);
              g_set_error (error, GTK_BUILDER_ERROR,
                           GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION,
                           _("Invalid type function on line %d: '%s'"),
                           line, values[i]);
              return;
            }
        }
      else
	{
	  error_invalid_attribute (data, element_name, names[i], error);
	  return;
	}
    }

  if (!object_class)
    {
      error_missing_attribute (data, element_name, "class", error);
      return;
    }

  if (!object_id)
    {
      error_missing_attribute (data, element_name, "id", error);
      return;
    }

  ++data->cur_object_level;

  /* check if we reached a requested object (if it is specified) */
  if (data->requested_objects && !data->inside_requested_object)
    {
      if (is_requested_object (object_id, data))
        {
          data->requested_object_level = data->cur_object_level;

          GTK_NOTE (BUILDER, g_print ("requested object \"%s\" found at level %d\n",
                                      object_id,
                                      data->requested_object_level));

          data->inside_requested_object = TRUE;
        }
      else
        {
          g_free (object_class);
          g_free (object_id);
          g_free (constructor);
          return;
        }
    }

  object_info = g_slice_new0 (ObjectInfo);
  object_info->class_name = object_class;
  object_info->id = object_id;
  object_info->constructor = constructor;
  state_push (data, object_info);
  object_info->tag.name = element_name;

  if (child_info)
    object_info->parent = (CommonInfo*)child_info;

  g_markup_parse_context_get_position (context, &line, NULL);
  line2 = GPOINTER_TO_INT (g_hash_table_lookup (data->object_ids, object_id));
  if (line2 != 0)
    {
      g_set_error (error, GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_DUPLICATE_ID,
                   _("Duplicate object id '%s' on line %d (previously on line %d)"),
                   object_id, line, line2);
      return;
    }


  g_hash_table_insert (data->object_ids, g_strdup (object_id), GINT_TO_POINTER (line));
}
Esempio n. 21
0
static void
gtk_widget_query_size_for_orientation (GtkWidget        *widget,
                                       GtkOrientation    orientation,
                                       gint              for_size,
                                       gint             *minimum_size,
                                       gint             *natural_size)
{
  SizeRequestCache *cache;
  gint min_size = 0;
  gint nat_size = 0;
  gboolean found_in_cache;

  if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_CONSTANT_SIZE)
    for_size = -1;

  cache = _gtk_widget_peek_request_cache (widget);
  found_in_cache = _gtk_size_request_cache_lookup (cache,
                                                   orientation,
                                                   for_size,
                                                   &min_size,
                                                   &nat_size);
  
  if (!found_in_cache)
    {
      gint adjusted_min, adjusted_natural, adjusted_for_size = for_size;

      G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
      gtk_widget_ensure_style (widget);
      G_GNUC_END_IGNORE_DEPRECATIONS;

      if (orientation == GTK_ORIENTATION_HORIZONTAL)
        {
          if (for_size < 0)
            {
	      push_recursion_check (widget, orientation, for_size);
              GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_size, &nat_size);
	      pop_recursion_check (widget, orientation);
            }
          else
            {
              gint ignored_position = 0;
              gint minimum_height;
              gint natural_height;

	      /* Pull the base natural height from the cache as it's needed to adjust
	       * the proposed 'for_size' */
	      gtk_widget_get_preferred_height (widget, &minimum_height, &natural_height);

              /* convert for_size to unadjusted height (for_size is a proposed allocation) */
              GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
                                                                     GTK_ORIENTATION_VERTICAL,
                                                                     &minimum_height,
								     &natural_height,
                                                                     &ignored_position,
                                                                     &adjusted_for_size);

	      push_recursion_check (widget, orientation, for_size);
              GTK_WIDGET_GET_CLASS (widget)->get_preferred_width_for_height (widget, 
									     MAX (adjusted_for_size, minimum_height),
									     &min_size, &nat_size);
	      pop_recursion_check (widget, orientation);
            }
        }
      else
        {
          if (for_size < 0)
            {
	      push_recursion_check (widget, orientation, for_size);
              GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, &min_size, &nat_size);
	      pop_recursion_check (widget, orientation);
            }
          else
            {
              gint ignored_position = 0;
              gint minimum_width;
              gint natural_width;

	      /* Pull the base natural width from the cache as it's needed to adjust
	       * the proposed 'for_size' */
	      gtk_widget_get_preferred_width (widget, &minimum_width, &natural_width);

              /* convert for_size to unadjusted width (for_size is a proposed allocation) */
              GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
                                                                     GTK_ORIENTATION_HORIZONTAL,
								     &minimum_width,
                                                                     &natural_width,
                                                                     &ignored_position,
                                                                     &adjusted_for_size);

	      push_recursion_check (widget, orientation, for_size);
              GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget, 
									     MAX (adjusted_for_size, minimum_width),
									     &min_size, &nat_size);
	      pop_recursion_check (widget, orientation);
            }
        }

      if (min_size > nat_size)
        {
          g_warning ("%s %p reported min size %d and natural size %d in %s(); natural size must be >= min size",
                     G_OBJECT_TYPE_NAME (widget), widget, min_size, nat_size, get_vfunc_name (orientation, for_size));
        }

      adjusted_min     = min_size;
      adjusted_natural = nat_size;
      GTK_WIDGET_GET_CLASS (widget)->adjust_size_request (widget,
                                                          orientation,
                                                          &adjusted_min,
                                                          &adjusted_natural);

      if (adjusted_min < min_size ||
          adjusted_natural < nat_size)
        {
          g_warning ("%s %p adjusted size %s min %d natural %d must not decrease below min %d natural %d",
                     G_OBJECT_TYPE_NAME (widget), widget,
                     orientation == GTK_ORIENTATION_VERTICAL ? "vertical" : "horizontal",
                     adjusted_min, adjusted_natural,
                     min_size, nat_size);
          /* don't use the adjustment */
        }
      else if (adjusted_min > adjusted_natural)
        {
          g_warning ("%s %p adjusted size %s min %d natural %d original min %d natural %d has min greater than natural",
                     G_OBJECT_TYPE_NAME (widget), widget,
                     orientation == GTK_ORIENTATION_VERTICAL ? "vertical" : "horizontal",
                     adjusted_min, adjusted_natural,
                     min_size, nat_size);
          /* don't use the adjustment */
        }
      else
        {
          /* adjustment looks good */
          min_size = adjusted_min;
          nat_size = adjusted_natural;
        }

      _gtk_size_request_cache_commit (cache,
                                      orientation,
                                      for_size,
                                      min_size,
                                      nat_size);
    }

  if (minimum_size)
    *minimum_size = min_size;

  if (natural_size)
    *natural_size = nat_size;

  g_assert (min_size <= nat_size);

  GTK_NOTE (SIZE_REQUEST,
            g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d (hit cache: %s)\n",
                     widget, G_OBJECT_TYPE_NAME (widget),
                     orientation == GTK_ORIENTATION_HORIZONTAL ?
                     "width for height" : "height for width" ,
                     for_size, min_size, nat_size,
                     found_in_cache ? "yes" : "no"));
}
Esempio n. 22
0
/* This is the main function that checks for a cached size and
 * possibly queries the widget class to compute the size if it's
 * not cached. If the for_size here is -1, then get_preferred_width()
 * or get_preferred_height() will be used.
 */
static void
compute_size_for_orientation (GtkWidget         *widget,
                              GtkSizeGroupMode   orientation,
                              gint               for_size,
                              gint              *minimum_size,
                              gint              *natural_size)
{
  CachedSize       *cached_size;
  gboolean          found_in_cache = FALSE;
  gint              min_size = 0;
  gint              nat_size = 0;

  found_in_cache = get_cached_size (widget, orientation, for_size, &cached_size);

  if (!found_in_cache)
    {
      gint adjusted_min, adjusted_natural, adjusted_for_size = for_size;

      gtk_widget_ensure_style (widget);

      if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
        {
          if (for_size < 0)
            {
	      push_recursion_check (widget, orientation, for_size);
              GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_size, &nat_size);
	      pop_recursion_check (widget, orientation);
            }
          else
            {
              gint ignored_position = 0;
              gint minimum_height;
              gint natural_height;

	      /* Pull the base natural height from the cache as it's needed to adjust
	       * the proposed 'for_size' */
	      gtk_widget_get_preferred_height (widget, &minimum_height, &natural_height);

              /* convert for_size to unadjusted height (for_size is a proposed allocation) */
              GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
                                                                     GTK_ORIENTATION_VERTICAL,
                                                                     &minimum_height,
								     &natural_height,
                                                                     &ignored_position,
                                                                     &adjusted_for_size);

	      push_recursion_check (widget, orientation, for_size);
              GTK_WIDGET_GET_CLASS (widget)->get_preferred_width_for_height (widget, 
									     MAX (adjusted_for_size, minimum_height),
									     &min_size, &nat_size);
	      pop_recursion_check (widget, orientation);
            }
        }
      else
        {
          if (for_size < 0)
            {
	      push_recursion_check (widget, orientation, for_size);
              GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, &min_size, &nat_size);
	      pop_recursion_check (widget, orientation);
            }
          else
            {
              gint ignored_position = 0;
              gint minimum_width;
              gint natural_width;

	      /* Pull the base natural width from the cache as it's needed to adjust
	       * the proposed 'for_size' */
	      gtk_widget_get_preferred_width (widget, &minimum_width, &natural_width);

              /* convert for_size to unadjusted width (for_size is a proposed allocation) */
              GTK_WIDGET_GET_CLASS (widget)->adjust_size_allocation (widget,
                                                                     GTK_ORIENTATION_HORIZONTAL,
								     &minimum_width,
                                                                     &natural_width,
                                                                     &ignored_position,
                                                                     &adjusted_for_size);

	      push_recursion_check (widget, orientation, for_size);
              GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget, 
									     MAX (adjusted_for_size, minimum_width),
									     &min_size, &nat_size);
	      pop_recursion_check (widget, orientation);
            }
        }

      if (min_size > nat_size)
        {
          g_warning ("%s %p reported min size %d and natural size %d; natural size must be >= min size",
                     G_OBJECT_TYPE_NAME (widget), widget, min_size, nat_size);
        }

      if (orientation == GTK_SIZE_GROUP_HORIZONTAL)
          _gtk_widget_set_width_request_needed (widget, FALSE);
      else
          _gtk_widget_set_height_request_needed (widget, FALSE);

      adjusted_min     = min_size;
      adjusted_natural = nat_size;
      GTK_WIDGET_GET_CLASS (widget)->adjust_size_request (widget,
                                                          orientation == GTK_SIZE_GROUP_HORIZONTAL ?
                                                          GTK_ORIENTATION_HORIZONTAL :
                                                          GTK_ORIENTATION_VERTICAL,
                                                          &adjusted_min,
                                                          &adjusted_natural);

      if (adjusted_min < min_size ||
          adjusted_natural < nat_size)
        {
          g_warning ("%s %p adjusted size %s min %d natural %d must not decrease below min %d natural %d",
                     G_OBJECT_TYPE_NAME (widget), widget,
                     orientation == GTK_SIZE_GROUP_VERTICAL ? "vertical" : "horizontal",
                     adjusted_min, adjusted_natural,
                     min_size, nat_size);
          /* don't use the adjustment */
        }
      else if (adjusted_min > adjusted_natural)
        {
          g_warning ("%s %p adjusted size %s min %d natural %d original min %d natural %d has min greater than natural",
                     G_OBJECT_TYPE_NAME (widget), widget,
                     orientation == GTK_SIZE_GROUP_VERTICAL ? "vertical" : "horizontal",
                     adjusted_min, adjusted_natural,
                     min_size, nat_size);
          /* don't use the adjustment */
        }
      else
        {
          /* adjustment looks good */
          min_size = adjusted_min;
          nat_size = adjusted_natural;
        }

      /* Update size-groups with our request and update our cached requests
       * with the size-group values in a single pass.
       */
      _gtk_size_group_bump_requisition (widget,
					orientation,
					&min_size,
					&nat_size);

      commit_cached_size (widget, orientation, for_size, min_size, nat_size);
    }
  else
    {
      min_size = cached_size->minimum_size;
      nat_size = cached_size->natural_size;
    }

  if (minimum_size)
    *minimum_size = min_size;

  if (natural_size)
    *natural_size = nat_size;

  g_assert (min_size <= nat_size);

  GTK_NOTE (SIZE_REQUEST,
            g_print ("[%p] %s\t%s: %d is minimum %d and natural: %d (hit cache: %s)\n",
                     widget, G_OBJECT_TYPE_NAME (widget),
                     orientation == GTK_SIZE_GROUP_HORIZONTAL ?
                     "width for height" : "height for width" ,
                     for_size, min_size, nat_size,
                     found_in_cache ? "yes" : "no"));

}