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

📄 main.c

📁 linux下电话本所依赖的一些图形库
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <config.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <gtk/gtk.h>#include <glib/gstdio.h>#include <demos.h>static GtkTextBuffer *info_buffer;static GtkTextBuffer *source_buffer;static gchar *current_file = NULL;enum {  TITLE_COLUMN,  FILENAME_COLUMN,  FUNC_COLUMN,  ITALIC_COLUMN,  NUM_COLUMNS};typedef struct _CallbackData CallbackData;struct _CallbackData{  GtkTreeModel *model;  GtkTreePath *path;};#ifdef G_OS_WIN32#undef DEMOCODEDIRstatic char *get_democodedir (void){  static char *result = NULL;  if (result == NULL)    {      result = g_win32_get_package_installation_directory (NULL, NULL);      if (result == NULL)	result = "unknown-location";      result = g_strconcat (result, "\\share\\gtk-2.0\\demo", NULL);    }  return result;}#define DEMOCODEDIR get_democodedir ()#endif/** * demo_find_file: * @base: base filename * @err:  location to store error, or %NULL. *  * Looks for @base first in the current directory, then in the * location GTK+ where it will be installed on make install, * returns the first file found. *  * Return value: the filename, if found or %NULL **/gchar *demo_find_file (const char *base,		GError    **err){  g_return_val_if_fail (err == NULL || *err == NULL, NULL);    if (g_file_test ("gtk-logo-rgb.gif", G_FILE_TEST_EXISTS) &&      g_file_test (base, G_FILE_TEST_EXISTS))    return g_strdup (base);  else    {      char *filename = g_build_filename (DEMOCODEDIR, base, NULL);      if (!g_file_test (filename, G_FILE_TEST_EXISTS))	{	  g_set_error (err, G_FILE_ERROR, G_FILE_ERROR_NOENT,		       "Cannot find demo data file \"%s\"", base);	  g_free (filename);	  return NULL;	}      return filename;    }}static voidwindow_closed_cb (GtkWidget *window, gpointer data){  CallbackData *cbdata = data;  GtkTreeIter iter;  gboolean italic;  gtk_tree_model_get_iter (cbdata->model, &iter, cbdata->path);  gtk_tree_model_get (GTK_TREE_MODEL (cbdata->model), &iter,		      ITALIC_COLUMN, &italic,		      -1);  if (italic)    gtk_tree_store_set (GTK_TREE_STORE (cbdata->model), &iter,			ITALIC_COLUMN, !italic,			-1);  gtk_tree_path_free (cbdata->path);  g_free (cbdata);}gbooleanread_line (FILE *stream, GString *str){  int n_read = 0;  #ifdef HAVE_FLOCKFILE  flockfile (stream);#endif  g_string_truncate (str, 0);    while (1)    {      int c;      #ifdef HAVE_FLOCKFILE      c = getc_unlocked (stream);#else      c = getc (stream);#endif      if (c == EOF)	goto done;      else	n_read++;      switch (c)	{	case '\r':	case '\n':	  {#ifdef HAVE_FLOCKFILE	    int next_c = getc_unlocked (stream);#else	    int next_c = getc (stream);#endif	    	    if (!(next_c == EOF ||		  (c == '\r' && next_c == '\n') ||		  (c == '\n' && next_c == '\r')))	      ungetc (next_c, stream);	    	    goto done;	  }	default:	  g_string_append_c (str, c);	}    } done:#ifdef HAVE_FLOCKFILE  funlockfile (stream);#endif  return n_read > 0;}/* Stupid syntax highlighting. * * No regex was used in the making of this highlighting. * It should only work for simple cases.  This is good, as * that's all we should have in the demos. *//* This code should not be used elsewhere, except perhaps as an example of how * to iterate through a text buffer. */enum {  STATE_NORMAL,  STATE_IN_COMMENT};static gchar *tokens[] ={  "/*",  "\"",  NULL};static gchar *types[] ={  "static",  "const ",  "void",  "gint",  "int ",  "char ",  "gchar ",  "gfloat",  "float",  "gint8",  "gint16",  "gint32",  "guint",  "guint8",  "guint16",  "guint32",  "guchar",  "glong",  "gboolean" ,  "gshort",  "gushort",  "gulong",  "gdouble",  "gldouble",  "gpointer",  "NULL",  "GList",  "GSList",  "FALSE",  "TRUE",  "FILE ",  "GtkObject ",  "GtkColorSelection ",  "GtkWidget ",  "GtkButton ",  "GdkColor ",  "GdkRectangle ",  "GdkEventExpose ",  "GdkGC ",  "GdkPixbufLoader ",  "GdkPixbuf ",  "GError",  "size_t",  NULL};static gchar *control[] ={  " if ",  " while ",  " else",  " do ",  " for ",  "?",  ":",  "return ",  "goto ",  NULL};voidparse_chars (gchar     *text,	     gchar    **end_ptr,	     gint      *state,	     gchar    **tag,	     gboolean   start){  gint i;  gchar *next_token;  /* Handle comments first */  if (*state == STATE_IN_COMMENT)    {      *end_ptr = strstr (text, "*/");      if (*end_ptr)	{	  *end_ptr += 2;	  *state = STATE_NORMAL;	  *tag = "comment";	}      return;    }  *tag = NULL;  *end_ptr = NULL;  /* check for comment */  if (!strncmp (text, "/*", 2))    {      *end_ptr = strstr (text, "*/");      if (*end_ptr)	*end_ptr += 2;      else	*state = STATE_IN_COMMENT;      *tag = "comment";      return;    }  /* check for preprocessor defines */  if (*text == '#' && start)    {      *end_ptr = NULL;      *tag = "preprocessor";      return;    }  /* functions */  if (start && * text != '\t' && *text != ' ' && *text != '{' && *text != '}')    {      if (strstr (text, "("))	{	  *end_ptr = strstr (text, "(");	  *tag = "function";	  return;	}    }  /* check for types */  for (i = 0; types[i] != NULL; i++)    if (!strncmp (text, types[i], strlen (types[i])))      {	*end_ptr = text + strlen (types[i]);	*tag = "type";	return;      }  /* check for control */  for (i = 0; control[i] != NULL; i++)    if (!strncmp (text, control[i], strlen (control[i])))      {	*end_ptr = text + strlen (control[i]);	*tag = "control";	return;      }  /* check for string */  if (text[0] == '"')    {      gint maybe_escape = FALSE;      *end_ptr = text + 1;      *tag = "string";      while (**end_ptr != '\000')	{	  if (**end_ptr == '\"' && !maybe_escape)	    {	      *end_ptr += 1;	      return;	    }	  if (**end_ptr == '\\')	    maybe_escape = TRUE;	  else	    maybe_escape = FALSE;	  *end_ptr += 1;	}      return;    }  /* not at the start of a tag.  Find the next one. */  for (i = 0; tokens[i] != NULL; i++)    {      next_token = strstr (text, tokens[i]);      if (next_token)	{	  if (*end_ptr)	    *end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;	  else	    *end_ptr = next_token;	}    }  for (i = 0; types[i] != NULL; i++)    {      next_token = strstr (text, types[i]);      if (next_token)	{	  if (*end_ptr)	    *end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;	  else	    *end_ptr = next_token;	}    }  for (i = 0; control[i] != NULL; i++)    {      next_token = strstr (text, control[i]);      if (next_token)	{	  if (*end_ptr)	    *end_ptr = (*end_ptr<next_token)?*end_ptr:next_token;	  else	    *end_ptr = next_token;	}    }}/* While not as cool as c-mode, this will do as a quick attempt at highlighting */static voidfontify (void){  GtkTextIter start_iter, next_iter, tmp_iter;  gint state;  gchar *text;  gchar *start_ptr, *end_ptr;  gchar *tag;  state = STATE_NORMAL;  gtk_text_buffer_get_iter_at_offset (source_buffer, &start_iter, 0);  next_iter = start_iter;  while (gtk_text_iter_forward_line (&next_iter))    {      gboolean start = TRUE;      start_ptr = text = gtk_text_iter_get_text (&start_iter, &next_iter);      do	{	  parse_chars (start_ptr, &end_ptr, &state, &tag, start);	  start = FALSE;	  if (end_ptr)	    {	      tmp_iter = start_iter;	      gtk_text_iter_forward_chars (&tmp_iter, end_ptr - start_ptr);	    }	  else	    {	      tmp_iter = next_iter;	    }	  if (tag)	    gtk_text_buffer_apply_tag_by_name (source_buffer, tag, &start_iter, &tmp_iter);	  start_iter = tmp_iter;	  start_ptr = end_ptr;	}      while (end_ptr);      g_free (text);      start_iter = next_iter;    }}voidload_file (const gchar *filename){  FILE *file;  GtkTextIter start, end;  char *full_filename;  GError *err = NULL;  GString *buffer = g_string_new (NULL);  int state = 0;  gboolean in_para = 0;  if (current_file && !strcmp (current_file, filename))    {      g_string_free (buffer, TRUE);      return;    }  g_free (current_file);  current_file = g_strdup (filename);    gtk_text_buffer_get_bounds (info_buffer, &start, &end);

⌨️ 快捷键说明

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