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

📄 changedisplay.c

📁 Linux下gtk图形界面开发的各种gtk控件调用方法示例
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Change Display *  * Demonstrates migrating a window between different displays and * screens. A display is a mouse and keyboard with some number of * associated monitors. A screen is a set of monitors grouped * into a single physical work area. The neat thing about having * multiple displays is that they can be on a completely separate * computers, as long as there is a network connection to the * computer where the application is running. * * Only some of the windowing systems where GTK+ runs have the * concept of multiple displays and screens. (The X Window System * is the main example.) Other windowing systems can only * handle one keyboard and mouse, and combine all monitors into * a single screen. * * This is a moderately complex example, and demonstrates: * *  - Tracking the currently open displays and screens * *  - Changing the screen for a window * *  - Letting the user choose a window by clicking on it *  *  - Using GtkListStore and GtkTreeView * *  - Using GtkDialog */#include <string.h>#include <gtk/gtk.h>#include "demo-common.h"/* The ChangeDisplayInfo structure corresponds to a toplevel window and * holds pointers to widgets inside the toplevel window along with other * information about the contents of the window. * This is a common organizational structure in real applications. */typedef struct _ChangeDisplayInfo ChangeDisplayInfo;struct _ChangeDisplayInfo{  GtkWidget *window;  GtkSizeGroup *size_group;  GtkTreeModel *display_model;  GtkTreeModel *screen_model;  GtkTreeSelection *screen_selection;    GdkDisplay *current_display;  GdkScreen *current_screen;};/* These enumerations provide symbolic names for the columns * in the two GtkListStore models. */enum{  DISPLAY_COLUMN_NAME,  DISPLAY_COLUMN_DISPLAY,  DISPLAY_NUM_COLUMNS};enum{  SCREEN_COLUMN_NUMBER,  SCREEN_COLUMN_SCREEN,  SCREEN_NUM_COLUMNS};/* Finds the toplevel window under the mouse pointer, if any. */static GtkWidget *find_toplevel_at_pointer (GdkDisplay *display){  GdkWindow *pointer_window;  GtkWidget *widget = NULL;  pointer_window = gdk_display_get_window_at_pointer (display, NULL, NULL);  /* The user data field of a GdkWindow is used to store a pointer   * to the widget that created it.   */  if (pointer_window)    gdk_window_get_user_data (pointer_window, (gpointer*) &widget);  return widget ? gtk_widget_get_toplevel (widget) : NULL;}static gbooleanbutton_release_event_cb (GtkWidget       *widget,			 GdkEventButton  *event,			 gboolean        *clicked){  *clicked = TRUE;  return TRUE;}/* Asks the user to click on a window, then waits for them click * the mouse. When the mouse is released, returns the toplevel * window under the pointer, or NULL, if there is none. */static GtkWidget *query_for_toplevel (GdkScreen  *screen,		    const char *prompt){  GdkDisplay *display = gdk_screen_get_display (screen);  GtkWidget *popup, *label, *frame;  GdkCursor *cursor;  GtkWidget *toplevel = NULL;    popup = gtk_window_new (GTK_WINDOW_POPUP);  gtk_window_set_screen (GTK_WINDOW (popup), screen);  gtk_window_set_modal (GTK_WINDOW (popup), TRUE);  gtk_window_set_position (GTK_WINDOW (popup), GTK_WIN_POS_CENTER);    frame = gtk_frame_new (NULL);  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);  gtk_container_add (GTK_CONTAINER (popup), frame);    label = gtk_label_new (prompt);  gtk_misc_set_padding (GTK_MISC (label), 10, 10);  gtk_container_add (GTK_CONTAINER (frame), label);    gtk_widget_show_all (popup);  cursor = gdk_cursor_new_for_display (display, GDK_CROSSHAIR);    if (gdk_pointer_grab (popup->window, FALSE,			GDK_BUTTON_RELEASE_MASK,			NULL,			cursor,			GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS)    {      gboolean clicked = FALSE;            g_signal_connect (popup, "button-release-event",			G_CALLBACK (button_release_event_cb), &clicked);            /* Process events until clicked is set by button_release_event_cb.       * We pass in may_block=TRUE since we want to wait if there       * are no events currently.       */      while (!clicked)	g_main_context_iteration (NULL, TRUE);            toplevel = find_toplevel_at_pointer (gdk_screen_get_display (screen));      if (toplevel == popup)	toplevel = NULL;    }        gdk_cursor_unref (cursor);  gtk_widget_destroy (popup);  gdk_flush ();			/* Really release the grab */    return toplevel;}/* Prompts the user for a toplevel window to move, and then moves * that window to the currently selected display */static voidquery_change_display (ChangeDisplayInfo *info){  GdkScreen *screen = gtk_widget_get_screen (info->window);  GtkWidget *toplevel;  toplevel = query_for_toplevel (screen,				 "Please select the toplevel\n"				 "to move to the new screen");  if (toplevel)    gtk_window_set_screen (GTK_WINDOW (toplevel), info->current_screen);  else    gdk_display_beep (gdk_screen_get_display (screen));}/* Fills in the screen list based on the current display */static voidfill_screens (ChangeDisplayInfo *info){  gtk_list_store_clear (GTK_LIST_STORE (info->screen_model));  if (info->current_display)    {      gint n_screens = gdk_display_get_n_screens (info->current_display);      gint i;            for (i = 0; i < n_screens; i++)	{	  GdkScreen *screen = gdk_display_get_screen (info->current_display, i);	  GtkTreeIter iter;	  	  gtk_list_store_append (GTK_LIST_STORE (info->screen_model), &iter);	  gtk_list_store_set (GTK_LIST_STORE (info->screen_model), &iter,			      SCREEN_COLUMN_NUMBER, i,			      SCREEN_COLUMN_SCREEN, screen,			      -1);	  if (i == 0)	    gtk_tree_selection_select_iter (info->screen_selection, &iter);	}    }}/* Called when the user clicks on a button in our dialog or * closes the dialog through the window manager. Unless the * "Change" button was clicked, we destroy the dialog. */static voidresponse_cb (GtkDialog         *dialog,	     gint               response_id,	     ChangeDisplayInfo *info){  if (response_id == GTK_RESPONSE_OK)    query_change_display (info);  else    gtk_widget_destroy (GTK_WIDGET (dialog));}/* Called when the user clicks on "Open..." in the display * frame. Prompts for a new display, and then opens a connection * to that display. */static voidopen_display_cb (GtkWidget         *button,		 ChangeDisplayInfo *info){  GtkWidget *dialog;  GtkWidget *display_entry;  GtkWidget *dialog_label;  gchar *new_screen_name = NULL;  GdkDisplay *result = NULL;    dialog = gtk_dialog_new_with_buttons ("Open Display",					GTK_WINDOW (info->window),					GTK_DIALOG_MODAL,					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,					GTK_STOCK_OK, GTK_RESPONSE_OK,					NULL);  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);  display_entry = gtk_entry_new ();  gtk_entry_set_activates_default (GTK_ENTRY (display_entry), TRUE);  dialog_label =    gtk_label_new ("Please enter the name of\nthe new display\n");  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), dialog_label);  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), display_entry);  gtk_widget_grab_focus (display_entry);  gtk_widget_show_all (GTK_BIN (dialog)->child);    while (!result)    {      gint response_id = gtk_dialog_run (GTK_DIALOG (dialog));      if (response_id != GTK_RESPONSE_OK)	break;            new_screen_name = gtk_editable_get_chars (GTK_EDITABLE (display_entry),						0, -1);      if (strcmp (new_screen_name, "") != 0)	{	  result = gdk_display_open (new_screen_name);	  if (!result)	    {	      gchar *error_msg =		g_strdup_printf  ("Can't open display :\n\t%s\nplease try another one\n",				  new_screen_name);	      gtk_label_set_text (GTK_LABEL (dialog_label), error_msg);	      g_free (error_msg);	    }	  g_free (new_screen_name);	}    }    gtk_widget_destroy (dialog);}/* Called when the user clicks on the "Close" button in the * "Display" frame. Closes the selected display. */static voidclose_display_cb (GtkWidget         *button,		  ChangeDisplayInfo *info){  if (info->current_display)    gdk_display_close (info->current_display);}/* Called when the selected row in the display list changes. * Updates info->current_display, then refills the list of * screens. */static voiddisplay_changed_cb (GtkTreeSelection  *selection,		    ChangeDisplayInfo *info){  GtkTreeModel *model;  GtkTreeIter iter;  if (info->current_display)    g_object_unref (info->current_display);  if (gtk_tree_selection_get_selected (selection, &model, &iter))    gtk_tree_model_get (model, &iter,			DISPLAY_COLUMN_DISPLAY, &info->current_display,			-1);  else    info->current_display = NULL;  fill_screens (info);}/* Called when the selected row in the sceen list changes. * Updates info->current_screen. */static voidscreen_changed_cb (GtkTreeSelection  *selection,		   ChangeDisplayInfo *info)

⌨️ 快捷键说明

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