1 /*
2 * Copyright (C) 1995, 1996 Karl-Johan Johnsson.
3 */
4
5 #include <X11/IntrinsicP.h>
6 #include <X11/StringDefs.h>
7
8 #include "Compat.h"
9 #include "Util.h"
10 #include "CloseShP.h"
11
12 static XtResource resources[] = {
13 {XtNinput, XtCInput, XtRBool, sizeof(Bool),
14 XtOffsetOf(CloseShellRec, wm.wm_hints.input),
15 XtRImmediate, (XtPointer)True},
16 {XtNallowShellResize, XtCAllowShellResize, XtRBoolean, sizeof(Boolean),
17 XtOffsetOf(CloseShellRec, shell.allow_shell_resize),
18 XtRImmediate, (XtPointer)True},
19 #define offset(field) XtOffsetOf(CloseShellRec, close_shell.field)
20 {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
21 offset(cursor), XtRString, (XtPointer)"top_left_arrow"},
22 {XtNcloseCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
23 offset(close_callback), XtRImmediate, (XtPointer)NULL},
24 #undef offset
25 };
26
27 static void ClassPartInitialize(WidgetClass);
28 static void Realize(Widget, XtValueMask*, XSetWindowAttributes*);
29 static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal*);
30
31 static void close_window(Widget, XEvent*, String*, Cardinal*);
32
33 static XtActionsRec actions[] = {
34 {"close-window", close_window},
35 };
36
37 static char translations[] =
38 "<Message>WM_PROTOCOLS: close-window() \n";
39
40 CloseShellClassRec closeShellClassRec = {
41 { /* core fields */
42 (WidgetClass) &transientShellClassRec, /* superclass */
43 "CloseShell", /* class_name */
44 sizeof(CloseShellRec), /* widget_size */
45 NULL, /* class_initialize */
46 ClassPartInitialize, /* class_part_initialize */
47 FALSE, /* class_inited */
48 NULL, /* initialize */
49 NULL, /* initialize_hook */
50 Realize, /* realize */
51 actions, /* actions */
52 XtNumber(actions), /* num_actions */
53 resources, /* resources */
54 XtNumber(resources), /* num_resources */
55 NULLQUARK, /* xrm_class */
56 TRUE, /* compress_motion */
57 FALSE, /* compress_exposure */
58 TRUE, /* compress_enterleave */
59 FALSE, /* visible_interest */
60 NULL, /* destroy */
61 XtInheritResize, /* resize */
62 NULL, /* expose */
63 SetValues, /* set_values */
64 NULL, /* set_values_hook */
65 XtInheritSetValuesAlmost, /* set_values_almost */
66 NULL, /* get_values_hook */
67 NULL, /* accept_focus */
68 XtVersion, /* version */
69 NULL, /* callback_private */
70 translations, /* tm_table */
71 NULL, /* query_geometry */
72 XtInheritDisplayAccelerator, /* display_accelerator */
73 NULL /* extension */
74 },
75 { /* composite fields */
76 XtInheritGeometryManager, /* geometry_manager */
77 XtInheritChangeManaged, /* change_managed */
78 XtInheritInsertChild, /* insert_child */
79 XtInheritDeleteChild, /* delete_child */
80 NULL, /* extension */
81 },
82 { /* shell fields */
83 NULL, /* extension */
84 },
85 { /* wm shell fields */
86 NULL, /* extension */
87 },
88 { /* vendor shell fields */
89 NULL, /* extension */
90 },
91 { /* transient shell fields */
92 NULL, /* extension */
93 },
94 { /* close_shell fields */
95 NULL, /* close_window */
96 NULL, /* extension */
97 }
98 };
99
100 WidgetClass closeShellWidgetClass = (WidgetClass)&closeShellClassRec;
101
102 /*************************************************************************/
103
close_window(Widget gw,XEvent * event,String * params,Cardinal * no_params)104 static void close_window(Widget gw, XEvent *event,
105 String *params, Cardinal *no_params)
106 {
107 CloseShellWidget w = (CloseShellWidget)gw;
108 CloseShellWidgetClass class;
109
110 class = (CloseShellWidgetClass)XtClass(w);
111 if (!class->close_shell_class.close_window) {
112 XtCallCallbackList((Widget)w, w->close_shell.close_callback, NULL);
113 return;
114 }
115
116 if (event->type == ClientMessage) {
117 Display *disp = XtDisplay(w);
118 Atom wm_delete_window = intern_atom(disp, "WM_DELETE_WINDOW");
119 Atom wm_protocols = intern_atom(disp, "WM_PROTOCOLS");
120
121 if (event->xclient.message_type == wm_protocols &&
122 event->xclient.data.l[0] == wm_delete_window)
123 class->close_shell_class.close_window((Widget)w);
124 }
125 }
126
127 /*************************************************************************/
128
ClassPartInitialize(WidgetClass gclass)129 static void ClassPartInitialize(WidgetClass gclass)
130 {
131 CloseShellWidgetClass class, super;
132
133 class = (CloseShellWidgetClass)gclass;
134 super = (CloseShellWidgetClass)class->core_class.superclass;
135
136 if (class->close_shell_class.close_window == XtInheritCloseWindow)
137 class->close_shell_class.close_window =
138 super->close_shell_class.close_window;
139 }
140
Realize(Widget gw,XtValueMask * mask,XSetWindowAttributes * attributes)141 static void Realize(Widget gw, XtValueMask *mask,
142 XSetWindowAttributes *attributes)
143 {
144 CloseShellWidget w = (CloseShellWidget)gw;
145 Display *disp = XtDisplay(w);
146 Atom wm_delete_window;
147
148 if (w->close_shell.cursor != None) {
149 *mask |= CWCursor;
150 attributes->cursor = w->close_shell.cursor;
151 }
152
153 transientShellWidgetClass->core_class.realize((Widget)w, mask, attributes);
154
155 wm_delete_window = intern_atom(disp, "WM_DELETE_WINDOW");
156 XSetWMProtocols(disp, XtWindow(w), &wm_delete_window, 1);
157 }
158
SetValues(Widget gcurrent,Widget grequest,Widget gnew,ArgList args,Cardinal * num_args)159 static Boolean SetValues(Widget gcurrent,
160 Widget grequest,
161 Widget gnew,
162 ArgList args,
163 Cardinal *num_args)
164 {
165 Boolean redisplay = False;
166 CloseShellWidget new = (CloseShellWidget)gnew;
167 CloseShellWidget current = (CloseShellWidget)gcurrent;
168
169 if (new->close_shell.cursor != current->close_shell.cursor)
170 CloseShellSetCursor((Widget)new, new->close_shell.cursor);
171
172 return redisplay;
173 }
174
175 /*************************************************************************/
176
CloseShellSetCursor(Widget gw,Cursor cursor)177 void CloseShellSetCursor(Widget gw, Cursor cursor)
178 {
179 CloseShellWidget w = (CloseShellWidget)gw;
180 Display *disp = XtDisplay(w);
181 Window win = XtWindow(w);
182
183 w->close_shell.cursor = cursor;
184 if (XtIsRealized((Widget)w))
185 XDefineCursor(disp, win, cursor);
186 }
187