1 /* 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #ifndef HEADLESS 27 28 #include <X11/IntrinsicP.h> 29 #include "VDrawingAreaP.h" 30 31 #endif /* !HEADLESS */ 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 36 #ifdef __linux__ 37 /* XXX: Shouldn't be necessary. */ 38 #include "awt_p.h" 39 #endif /* __linux__ */ 40 41 42 /****************************************************************** 43 * 44 * Provides Canvas widget which allows the X11 visual to be 45 * changed (the Motif DrawingArea restricts the visual to that 46 * of the parent widget). 47 * 48 ******************************************************************/ 49 50 51 /****************************************************************** 52 * 53 * VDrawingArea Widget Resources 54 * 55 ******************************************************************/ 56 57 #ifndef HEADLESS 58 #define Offset(x) (XtOffsetOf(VDrawingAreaRec, x)) 59 static XtResource resources[]= 60 { 61 { XtNvisual, XtCVisual, XtRVisual, sizeof(Visual*), 62 Offset(vdrawing_area.visual), XtRImmediate, CopyFromParent} 63 }; 64 65 66 static void Realize(); 67 static Boolean SetValues(); 68 static void Destroy (); 69 70 static XmBaseClassExtRec baseClassExtRec = { 71 NULL, 72 NULLQUARK, 73 XmBaseClassExtVersion, 74 sizeof(XmBaseClassExtRec), 75 NULL, /* InitializePrehook */ 76 NULL, /* SetValuesPrehook */ 77 NULL, /* InitializePosthook */ 78 NULL, /* SetValuesPosthook */ 79 NULL, /* secondaryObjectClass */ 80 NULL, /* secondaryCreate */ 81 NULL, /* getSecRes data */ 82 { 0 }, /* fastSubclass flags */ 83 NULL, /* getValuesPrehook */ 84 NULL, /* getValuesPosthook */ 85 NULL, /* classPartInitPrehook */ 86 NULL, /* classPartInitPosthook*/ 87 NULL, /* ext_resources */ 88 NULL, /* compiled_ext_resources*/ 89 0, /* num_ext_resources */ 90 FALSE, /* use_sub_resources */ 91 NULL, /* widgetNavigable */ 92 NULL, /* focusChange */ 93 NULL /* wrapper_data */ 94 }; 95 96 VDrawingAreaClassRec vDrawingAreaClassRec = { 97 { 98 /* Core class part */ 99 100 /* superclass */ (WidgetClass)&xmDrawingAreaClassRec, 101 /* class_name */ "VDrawingArea", 102 /* widget_size */ sizeof(VDrawingAreaRec), 103 /* class_initialize */ NULL, 104 /* class_part_initialize*/ NULL, 105 /* class_inited */ FALSE, 106 /* initialize */ NULL, 107 /* initialize_hook */ NULL, 108 /* realize */ Realize, 109 /* actions */ NULL, 110 /* num_actions */ 0, 111 /* resources */ resources, 112 /* num_resources */ XtNumber(resources), 113 /* xrm_class */ NULLQUARK, 114 /* compress_motion */ FALSE, 115 /* compress_exposure */ FALSE, 116 /* compress_enterleave*/ FALSE, 117 /* visible_interest */ FALSE, 118 /* destroy */ Destroy, 119 /* resize */ XtInheritResize, 120 /* expose */ XtInheritExpose, 121 /* set_values */ SetValues, 122 /* set_values_hook */ NULL, 123 /* set_values_almost */ XtInheritSetValuesAlmost, 124 /* get_values_hook */ NULL, 125 /* accept_focus */ NULL, 126 /* version */ XtVersion, 127 /* callback_offsets */ NULL, 128 /* tm_table */ NULL, 129 /* query_geometry */ NULL, 130 /* display_accelerator */ NULL, 131 /* extension */ NULL 132 }, 133 134 { /* composite_class fields */ 135 XtInheritGeometryManager, /* geometry_manager */ 136 XtInheritChangeManaged, /* change_managed */ 137 XtInheritInsertChild, /* insert_child */ 138 XtInheritDeleteChild, /* delete_child */ 139 NULL, /* extension */ 140 }, 141 142 { /* constraint_class fields */ 143 NULL, /* resource list */ 144 0, /* num resources */ 145 0, /* constraint size */ 146 NULL, /* init proc */ 147 NULL, /* destroy proc */ 148 NULL, /* set values proc */ 149 NULL, /* extension */ 150 }, 151 152 { /* manager_class fields */ 153 XtInheritTranslations, /* translations */ 154 NULL, /* syn_resources */ 155 0, /* num_get_resources */ 156 NULL, /* syn_cont_resources */ 157 0, /* num_get_cont_resources */ 158 XmInheritParentProcess, /* parent_process */ 159 NULL, /* extension */ 160 }, 161 162 { /* drawingArea class */ 163 /* extension */ NULL 164 }, 165 166 /* VDrawingArea class part */ 167 { 168 /* extension */ NULL 169 } 170 }; 171 172 WidgetClass vDrawingAreaClass = (WidgetClass)&vDrawingAreaClassRec; 173 174 static Boolean 175 SetValues(cw, rw, nw, args, num_args) 176 Widget cw; 177 Widget rw; 178 Widget nw; 179 ArgList args; 180 Cardinal *num_args; 181 { 182 VDrawingAreaWidget current = (VDrawingAreaWidget)cw; 183 VDrawingAreaWidget new_w = (VDrawingAreaWidget)nw; 184 185 if (new_w->vdrawing_area.visual != current->vdrawing_area.visual) { 186 new_w->vdrawing_area.visual = current->vdrawing_area.visual; 187 #ifdef DEBUG 188 fprintf(stdout, "VDrawingArea.SetValues: can't change visual from: visualID=%ld to visualID=%ld\n", 189 current->vdrawing_area.visual->visualid, 190 new_w->vdrawing_area.visual->visualid); 191 #endif 192 193 } 194 195 return (False); 196 } 197 198 int 199 FindWindowInList (Window parentWindow, Window *colormap_windows, int count) 200 { 201 int i; 202 203 for (i = 0; i < count; i++) 204 if (colormap_windows [i] == parentWindow) 205 return i; 206 return -1; 207 } 208 209 static void 210 Realize(w, value_mask, attributes) 211 Widget w; 212 XtValueMask *value_mask; 213 XSetWindowAttributes *attributes; 214 { 215 Widget parent; 216 Status status; 217 Window *colormap_windows; 218 Window *new_colormap_windows; 219 int count; 220 int i; 221 VDrawingAreaWidget vd = (VDrawingAreaWidget)w; 222 223 #ifdef DEBUG 224 fprintf(stdout, "VDrawingArea.Realize: visualID=%ld, depth=%d\n", 225 vd->vdrawing_area.visual->visualid, w->core.depth); 226 #endif 227 228 /* 4328588: 229 * Since we have our own Realize() function, we don't execute the one for 230 * our super-super class, XmManager, and miss the code which checks that 231 * height and width != 0. I've added that here. -bchristi 232 */ 233 if (!XtWidth(w)) XtWidth(w) = 1 ; 234 if (!XtHeight(w)) XtHeight(w) = 1 ; 235 236 w->core.window = XCreateWindow (XtDisplay (w), XtWindow (w->core.parent), 237 w->core.x, w->core.y, w->core.width, w->core.height, 238 0, w->core.depth, InputOutput, 239 vd->vdrawing_area.visual, 240 *value_mask, attributes ); 241 242 /* Need to add this window to the list of Colormap windows */ 243 parent = XtParent (w); 244 while ((parent != NULL) && (!(XtIsShell (parent)))) 245 parent = XtParent (parent); 246 if (parent == NULL) { 247 fprintf (stderr, "NO TopLevel widget?!\n"); 248 return; 249 } 250 251 status = XGetWMColormapWindows (XtDisplay (w), XtWindow (parent), 252 &colormap_windows, &count); 253 254 /* If status is zero, add this window and shell to the list 255 of colormap Windows */ 256 if (status == 0) { 257 new_colormap_windows = (Window *) calloc (2, sizeof (Window)); 258 new_colormap_windows [0] = XtWindow (w); 259 new_colormap_windows [1] = XtWindow (parent); 260 XSetWMColormapWindows (XtDisplay (w), XtWindow (parent), 261 new_colormap_windows, 2); 262 free (new_colormap_windows); 263 } else { 264 /* Check if parent is already in the list */ 265 int parent_entry = -1; 266 267 if (count > 0) 268 parent_entry = FindWindowInList (XtWindow (parent), 269 colormap_windows, count); 270 if (parent_entry == -1) { /* Parent not in list */ 271 new_colormap_windows = (Window *) calloc (count + 2, 272 sizeof (Window)); 273 new_colormap_windows [0] = XtWindow (w); 274 new_colormap_windows [1] = XtWindow (parent); 275 for (i = 0; i < count; i++) 276 new_colormap_windows [i + 2] = colormap_windows [i]; 277 XSetWMColormapWindows (XtDisplay (w), XtWindow (parent), 278 new_colormap_windows, count + 2); 279 280 } else { /* parent already in list, just add new window */ 281 new_colormap_windows = (Window *) calloc (count + 1, 282 sizeof (Window)); 283 new_colormap_windows [0] = XtWindow (w); 284 for (i = 0; i < count; i++) 285 new_colormap_windows [i + 1] = colormap_windows [i]; 286 XSetWMColormapWindows (XtDisplay (w), XtWindow (parent), 287 new_colormap_windows, count + 1); 288 } 289 free (new_colormap_windows); 290 XFree (colormap_windows); 291 } 292 293 294 } 295 296 static void 297 Destroy(Widget widget) 298 { 299 Status status; 300 Widget parent; 301 Window *colormap_windows; 302 Window *new_colormap_windows; 303 int count; 304 int listEntry; 305 int i; 306 int j; 307 308 /* Need to get this window's parent shell first */ 309 parent = XtParent (widget); 310 while ((parent != NULL) && (!(XtIsShell (parent)))) 311 parent = XtParent (parent); 312 if (parent == NULL) { 313 fprintf (stderr, "NO TopLevel widget?!\n"); 314 return; 315 } 316 317 status = XGetWMColormapWindows (XtDisplay (widget), XtWindow (parent), 318 &colormap_windows, &count); 319 320 /* If status is zero, then there were no colormap windows for 321 the parent ?? */ 322 323 if (status == 0) 324 return; 325 326 /* Remove this window from the list of colormap windows */ 327 listEntry = FindWindowInList (XtWindow (widget), colormap_windows, 328 count); 329 330 new_colormap_windows = (Window *) calloc (count - 1, sizeof (Window)); 331 j = 0; 332 for (i = 0; i < count; i++) { 333 if (i == listEntry) 334 continue; 335 new_colormap_windows [j] = colormap_windows [i]; 336 j++; 337 } 338 XSetWMColormapWindows (XtDisplay (widget), XtWindow (parent), 339 new_colormap_windows, count - 1); 340 free (new_colormap_windows); 341 XFree (colormap_windows); 342 343 } 344 #endif /* !HEADLESS */