1/* 2 * Copyright 2014 Olaf Seibert 3 */ 4 5/* 6 * Code to look at a few Motif Window Manager hints. 7 * 8 * Only the bits marked [v] are actually looked at. 9 * For the rest, ctwm has no concept, really. 10 * 11 * For some information about the meaning of the flags, see 12 * the manual page VendorShell(3) from the Motif library. 13 */ 14 15#include "ctwm.h" 16 17#include <stdio.h> 18 19#include "ctwm_atoms.h" 20#include "list.h" 21#include "mwmhints.h" 22#include "screen.h" 23 24bool 25GetMWMHints(Window w, MotifWmHints *mwmHints) 26{ 27 int success; 28 Atom actual_type; 29 int actual_format; 30 unsigned long nitems; 31 unsigned long bytes_after; 32 unsigned long *prop = NULL; 33 34 /* Defaults for when not found */ 35 mwmHints->flags = 0; 36 mwmHints->functions = 0; 37 mwmHints->decorations = 0; 38#ifdef FULL_MWM_DATA 39 mwmHints->input_mode = 0; 40 mwmHints->status = 0; 41#endif 42 43 success = XGetWindowProperty( 44 dpy, w, XA__MOTIF_WM_HINTS, 45 0, 5, /* long_offset, long long_length, */ 46 False, /* Bool delete, */ 47 AnyPropertyType,/* Atom req_type */ 48 &actual_type, /* Atom *actual_type_return, */ 49 &actual_format, /* int *actual_format_return, */ 50 &nitems, /* unsigned long *nitems_return, */ 51 &bytes_after, /* unsigned long * */ 52 (unsigned char **)&prop); /* unsigned char ** */ 53 54 if(success == Success && 55 actual_type == XA__MOTIF_WM_HINTS && 56 actual_format == 32 && 57 nitems >= 3) { 58 mwmHints->flags = (int)prop[0]; 59 mwmHints->functions = (int)prop[1]; 60 mwmHints->decorations = (int)prop[2]; 61#ifdef FULL_MWM_DATA 62 mwmHints->input_mode = (int)prop[3]; 63 mwmHints->status = (int)prop[4]; 64#endif 65 66 if(mwmHints->flags & MWM_HINTS_FUNCTIONS) { 67 if(mwmHints->functions & MWM_FUNC_ALL) { 68 mwmHints->functions ^= ~0; 69 } 70 } 71 if(mwmHints->flags & MWM_HINTS_DECORATIONS) { 72 if(mwmHints->decorations & MWM_DECOR_ALL) { 73 mwmHints->decorations ^= ~0; 74 } 75 } 76 77 success = true; 78 } 79 else { 80 success = false; 81 } 82 83 if(prop != NULL) { 84 XFree(prop); 85 } 86 87 return success; 88} 89 90 91 92/* 93 * Simple test wrappers 94 */ 95static bool 96mwm_sets_decorations(MotifWmHints *hints) 97{ 98 return (hints->flags & MWM_HINTS_DECORATIONS) ? true : false; 99} 100 101 102/* 1 = yes 0 = no -1 = no opinion */ 103int 104mwm_has_border(MotifWmHints *hints) 105{ 106 /* No opinion if hints don't set decoration info */ 107 if(!mwm_sets_decorations(hints)) { 108 return -1; 109 } 110 111 /* No opinion if the user told us to ignore it */ 112 if(LookInNameList(Scr->MWMIgnore, "DECOR_BORDER")) { 113 return -1; 114 } 115 116 /* No border if hints said so */ 117 if((hints->decorations & MWM_DECOR_BORDER) == 0) { 118 return 0; 119 } 120 121 /* Else border */ 122 return 1; 123} 124 125 126bool 127mwm_sets_title(MotifWmHints *hints) 128{ 129 /* Not if we don't have decoration info */ 130 if(!mwm_sets_decorations(hints)) { 131 return false; 132 } 133 134 /* Not if the user wants to ignore title frobbing */ 135 if(LookInNameList(Scr->MWMIgnore, "DECOR_TITLE")) { 136 return false; 137 } 138 139 /* Else we do have info to use */ 140 return true; 141} 142 143 144bool 145mwm_has_title(MotifWmHints *hints) 146{ 147 if(mwm_sets_decorations(hints) 148 && ((hints->decorations & MWM_DECOR_TITLE) == 0)) { 149 return false; 150 } 151 return true; 152} 153