00001 #include "bcbitmap.h"
00002 #include "bcclipboard.h"
00003 #include "bcdisplayinfo.h"
00004 #include "bcmenubar.h"
00005 #include "bcpixmap.h"
00006 #include "bcpopup.h"
00007 #include "bcpopupmenu.h"
00008 #include "bcrepeater.h"
00009 #include "bcresources.h"
00010 #include "bcsignals.h"
00011 #include "bcsubwindow.h"
00012 #include "bcwindowbase.h"
00013 #include "bcwindowevents.h"
00014 #include "colormodels.h"
00015 #include "colors.h"
00016 #include "condition.h"
00017 #include "cursors.h"
00018 #include "defaults.h"
00019 #include "fonts.h"
00020 #include "keys.h"
00021 #include "language.h"
00022 #include "sizes.h"
00023 #include "vframe.h"
00024
00025 #ifdef HAVE_GL
00026 #include <GL/gl.h>
00027 #endif
00028 #include <string.h>
00029 #include <unistd.h>
00030
00031 #include <X11/extensions/Xvlib.h>
00032 #include <X11/extensions/shape.h>
00033
00034
00035 BC_ResizeCall::BC_ResizeCall(int w, int h)
00036 {
00037 this->w = w;
00038 this->h = h;
00039 }
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 Mutex BC_WindowBase::opengl_lock;
00051
00052 BC_Resources BC_WindowBase::resources;
00053
00054 Window XGroupLeader = 0;
00055
00056 BC_WindowBase::BC_WindowBase()
00057 {
00058
00059 BC_WindowBase::initialize();
00060 }
00061
00062 BC_WindowBase::~BC_WindowBase()
00063 {
00064
00065 #ifdef HAVE_LIBXXF86VM
00066 if(window_type == VIDMODE_SCALED_WINDOW && vm_switched)
00067 {
00068 restore_vm();
00069 }
00070 #endif
00071
00072 hide_tooltip();
00073 if(window_type != MAIN_WINDOW)
00074 {
00075 if(top_level->active_menubar == this) top_level->active_menubar = 0;
00076 if(top_level->active_popup_menu == this) top_level->active_popup_menu = 0;
00077 if(top_level->active_subwindow == this) top_level->active_subwindow = 0;
00078 parent_window->subwindows->remove(this);
00079 }
00080
00081
00082
00083 is_deleting = 1;
00084 if(subwindows)
00085 {
00086 while (subwindows->total)
00087 {
00088
00089
00090 delete subwindows->values[0];
00091 }
00092 delete subwindows;
00093 }
00094
00095 XFreePixmap(top_level->display, pixmap);
00096 XDestroyWindow(top_level->display, win);
00097
00098 if(bg_pixmap && !shared_bg_pixmap) delete bg_pixmap;
00099 if(icon_pixmap) delete icon_pixmap;
00100 if(temp_bitmap) delete temp_bitmap;
00101
00102
00103 if(window_type == MAIN_WINDOW)
00104 {
00105
00106 XFreeGC(display, gc);
00107 #ifdef HAVE_XFT
00108 if(largefont_xft)
00109 XftFontClose (display, (XftFont*)largefont_xft);
00110 if(mediumfont_xft)
00111 XftFontClose (display, (XftFont*)mediumfont_xft);
00112 if(smallfont_xft)
00113 XftFontClose (display, (XftFont*)smallfont_xft);
00114 #endif
00115 flush();
00116
00117 XCloseDisplay(display);
00118
00119 clipboard->stop_clipboard();
00120 delete clipboard;
00121 }
00122 else
00123 {
00124 flush();
00125 }
00126
00127 resize_history.remove_all_objects();
00128 common_events.remove_all_objects();
00129 delete event_lock;
00130 delete event_condition;
00131 UNSET_ALL_LOCKS(this)
00132 }
00133
00134 int BC_WindowBase::initialize()
00135 {
00136 test_keypress = 0;
00137 is_deleting = 0;
00138 window_lock = 0;
00139 x = 0;
00140 y = 0;
00141 w = 0;
00142 h = 0;
00143 bg_color = -1;
00144 top_level = 0;
00145 parent_window = 0;
00146 subwindows = 0;
00147 xvideo_port_id = -1;
00148 video_on = 0;
00149 motion_events = 0;
00150 resize_events = 0;
00151 translation_events = 0;
00152 ctrl_mask = shift_mask = alt_mask = 0;
00153 cursor_x = cursor_y = button_number = 0;
00154 button_down = 0;
00155 button_pressed = 0;
00156 button_time1 = button_time2 = 0;
00157 double_click = 0;
00158 last_motion_win = 0;
00159 key_pressed = 0;
00160 active_menubar = 0;
00161 active_popup_menu = 0;
00162 active_subwindow = 0;
00163 bg_pixmap = 0;
00164 tooltip_text[0] = 0;
00165 persistant_tooltip = 0;
00166
00167 tooltip_popup = 0;
00168 tooltip_done = 0;
00169 current_font = MEDIUMFONT;
00170 current_color = BLACK;
00171 prev_cursor = current_cursor = ARROW_CURSOR;
00172 hourglass_total = 0;
00173 is_dragging = 0;
00174 shared_bg_pixmap = 0;
00175 icon_pixmap = 0;
00176 window_type = MAIN_WINDOW;
00177 translation_count = 0;
00178 x_correction = y_correction = 0;
00179 temp_bitmap = 0;
00180 tooltip_on = 0;
00181 temp_cursor = 0;
00182 toggle_value = 0;
00183 toggle_drag = 0;
00184 has_focus = 0;
00185 #ifdef HAVE_LIBXXF86VM
00186 vm_switched = 0;
00187 #endif
00188 xft_drawable = 0;
00189 largefont_xft = 0;
00190 mediumfont_xft = 0;
00191 smallfont_xft = 0;
00192
00193 event_lock = new Mutex("BC_WindowBase::event_lock");
00194 event_condition = new Condition(0, "BC_WindowBase::event_condition");
00195 event_thread = 0;
00196
00197 return 0;
00198 }
00199
00200 #define DEFAULT_EVENT_MASKS EnterWindowMask | \
00201 LeaveWindowMask | \
00202 ButtonPressMask | \
00203 ButtonReleaseMask | \
00204 PointerMotionMask | \
00205 FocusChangeMask
00206
00207
00208 int BC_WindowBase::create_window(BC_WindowBase *parent_window,
00209 char *title,
00210 int x,
00211 int y,
00212 int w,
00213 int h,
00214 int minw,
00215 int minh,
00216 int allow_resize,
00217 int private_color,
00218 int hide,
00219 int bg_color,
00220 char *display_name,
00221 int window_type,
00222 BC_Pixmap *bg_pixmap,
00223 int group_it)
00224 {
00225 XSetWindowAttributes attr;
00226 unsigned long mask;
00227 XSizeHints size_hints;
00228 int root_w;
00229 int root_h;
00230 #ifdef HAVE_LIBXXF86VM
00231 int vm;
00232 #endif
00233
00234 if(parent_window) top_level = parent_window->top_level;
00235
00236 #ifdef HAVE_LIBXXF86VM
00237 if(window_type == VIDMODE_SCALED_WINDOW)
00238 closest_vm(&vm,&w,&h);
00239 #endif
00240
00241 this->x = x;
00242 this->y = y;
00243 this->w = w;
00244 this->h = h;
00245 this->bg_color = bg_color;
00246 this->window_type = window_type;
00247 this->hidden = hide;
00248 this->private_color = private_color;
00249 this->parent_window = parent_window;
00250 this->bg_pixmap = bg_pixmap;
00251 this->allow_resize = allow_resize;
00252 strcpy(this->title, _(title));
00253 if(bg_pixmap) shared_bg_pixmap = 1;
00254
00255 if(parent_window) top_level = parent_window->top_level;
00256
00257 subwindows = new BC_SubWindowList;
00258
00259
00260 if(window_type == MAIN_WINDOW)
00261 {
00262 top_level = this;
00263 parent_window = this;
00264
00265
00266
00267 XInitThreads();
00268
00269
00270
00271 display = init_display(display_name);
00272
00273
00274
00275 root_w = get_root_w(1, 0);
00276 root_h = get_root_h(0);
00277 if(this->x + this->w > root_w) this->x = root_w - this->w;
00278 if(this->y + this->h > root_h) this->y = root_h - this->h;
00279 if(this->x < 0) this->x = 0;
00280 if(this->y < 0) this->y = 0;
00281 screen = DefaultScreen(display);
00282
00283 rootwin = RootWindow(display, screen);
00284 vis = DefaultVisual(display, screen);
00285 default_depth = DefaultDepth(display, screen);
00286 client_byte_order = (*(u_int32_t*)"a ") & 0x00000001;
00287 server_byte_order = (XImageByteOrder(display) == MSBFirst) ? 0 : 1;
00288
00289
00290
00291
00292 init_colors();
00293
00294 if(resources.use_shm < 0) resources.initialize_display(this);
00295 x_correction = get_resources()->get_left_border();
00296 y_correction = get_resources()->get_top_border();
00297
00298 if(this->bg_color == -1)
00299 this->bg_color = resources.get_bg_color();
00300 init_fonts();
00301 init_gc();
00302 init_cursors();
00303
00304
00305 mask = CWEventMask |
00306 CWBackPixel |
00307 CWColormap |
00308 CWCursor;
00309
00310 attr.event_mask = DEFAULT_EVENT_MASKS |
00311 StructureNotifyMask |
00312 KeyPressMask;
00313
00314 attr.background_pixel = get_color(this->bg_color);
00315 attr.colormap = cmap;
00316 attr.cursor = get_cursor_struct(ARROW_CURSOR);
00317
00318 win = XCreateWindow(display,
00319 rootwin,
00320 this->x,
00321 this->y,
00322 this->w,
00323 this->h,
00324 0,
00325 top_level->default_depth,
00326 InputOutput,
00327 vis,
00328 mask,
00329 &attr);
00330
00331 XGetNormalHints(display, win, &size_hints);
00332
00333 size_hints.flags = PSize | PMinSize | PMaxSize;
00334 size_hints.width = this->w;
00335 size_hints.height = this->h;
00336 size_hints.min_width = allow_resize ? minw : this->w;
00337 size_hints.max_width = allow_resize ? 32767 : this->w;
00338 size_hints.min_height = allow_resize ? minh : this->h;
00339 size_hints.max_height = allow_resize ? 32767 : this->h;
00340 if(x > -BC_INFINITY && x < BC_INFINITY)
00341 {
00342 size_hints.flags |= PPosition;
00343 size_hints.x = this->x;
00344 size_hints.y = this->y;
00345 }
00346
00347 XSetStandardProperties(display,
00348 win,
00349 title,
00350 title,
00351 None,
00352 0,
00353 0,
00354 &size_hints);
00355 get_atoms();
00356
00357 clipboard = new BC_Clipboard(display_name);
00358 clipboard->start_clipboard();
00359
00360 if (group_it)
00361 {
00362 Atom ClientLeaderXAtom;
00363 if (XGroupLeader == 0)
00364 XGroupLeader = win;
00365 char *instance_name = "cinelerra";
00366 char *class_name = "Cinelerra";
00367 XClassHint *class_hints = XAllocClassHint();
00368 class_hints->res_name = instance_name;
00369 class_hints->res_class = class_name;
00370 XSetClassHint(top_level->display, win, class_hints);
00371 XFree(class_hints);
00372 ClientLeaderXAtom = XInternAtom(display, "WM_CLIENT_LEADER", True);
00373 XChangeProperty(display,
00374 win,
00375 ClientLeaderXAtom,
00376 XA_WINDOW,
00377 32,
00378 PropModeReplace,
00379 (unsigned char *)&XGroupLeader,
00380 true);
00381
00382 }
00383
00384 }
00385
00386 #ifdef HAVE_LIBXXF86VM
00387 if(window_type == VIDMODE_SCALED_WINDOW && vm != -1)
00388 {
00389 scale_vm (vm);
00390 vm_switched = 1;
00391 }
00392 #endif
00393
00394 #ifdef HAVE_LIBXXF86VM
00395 if(window_type == POPUP_WINDOW || window_type == VIDMODE_SCALED_WINDOW)
00396 #else
00397 if(window_type == POPUP_WINDOW)
00398 #endif
00399 {
00400 mask = CWEventMask |
00401 CWBackPixel |
00402 CWColormap |
00403 CWOverrideRedirect |
00404 CWSaveUnder |
00405 CWCursor;
00406
00407 attr.event_mask = DEFAULT_EVENT_MASKS |
00408 KeyPressMask;
00409
00410 if(this->bg_color == -1)
00411 this->bg_color = resources.get_bg_color();
00412 attr.background_pixel = top_level->get_color(bg_color);
00413 attr.colormap = top_level->cmap;
00414 attr.cursor = top_level->get_cursor_struct(ARROW_CURSOR);
00415 attr.override_redirect = True;
00416 attr.save_under = True;
00417
00418 win = XCreateWindow(top_level->display,
00419 top_level->rootwin,
00420 this->x,
00421 this->y,
00422 this->w,
00423 this->h,
00424 0,
00425 top_level->default_depth,
00426 InputOutput,
00427 top_level->vis,
00428 mask,
00429 &attr);
00430 }
00431
00432 if(window_type == SUB_WINDOW)
00433 {
00434 mask = CWBackPixel | CWEventMask;
00435 attr.event_mask = DEFAULT_EVENT_MASKS;
00436 attr.background_pixel = top_level->get_color(this->bg_color);
00437 win = XCreateWindow(top_level->display,
00438 parent_window->win,
00439 this->x,
00440 this->y,
00441 this->w,
00442 this->h,
00443 0,
00444 top_level->default_depth,
00445 InputOutput,
00446 top_level->vis,
00447 mask,
00448 &attr);
00449 init_window_shape();
00450 XMapWindow(top_level->display, win);
00451 }
00452
00453
00454 pixmap = XCreatePixmap(top_level->display,
00455 win,
00456 this->w,
00457 this->h,
00458 top_level->default_depth);
00459
00460
00461 #ifdef HAVE_XFT
00462 if(get_resources()->use_xft)
00463 {
00464
00465
00466
00467
00468
00469 xft_drawable = XftDrawCreate(top_level->display,
00470 pixmap,
00471 top_level->vis,
00472 top_level->cmap);
00473
00474
00475
00476
00477
00478
00479 }
00480 #endif
00481
00482
00483 if(window_type == MAIN_WINDOW)
00484 {
00485 if(get_resources()->bg_image && !bg_pixmap && bg_color < 0)
00486 {
00487 this->bg_pixmap = new BC_Pixmap(this,
00488 get_resources()->bg_image,
00489 PIXMAP_OPAQUE);
00490 }
00491
00492 if(!hidden) show_window();
00493
00494 }
00495
00496
00497
00498
00499 draw_background(0, 0, this->w, this->h);
00500 flash();
00501
00502
00503 #ifdef HAVE_LIBXXF86VM
00504 if(window_type == POPUP_WINDOW || window_type == VIDMODE_SCALED_WINDOW)
00505 #else
00506 if(window_type == POPUP_WINDOW)
00507 #endif
00508 {
00509 init_window_shape();
00510 if(!hidden) show_window();
00511 }
00512 return 0;
00513 }
00514
00515 Display* BC_WindowBase::init_display(char *display_name)
00516 {
00517 Display* display;
00518
00519 if(display_name && display_name[0] == 0) display_name = NULL;
00520 if((display = XOpenDisplay(display_name)) == NULL)
00521 {
00522 printf("BC_WindowBase::init_display: cannot connect to X server %s\n",
00523 display_name);
00524 if(getenv("DISPLAY") == NULL)
00525 {
00526 printf("'DISPLAY' environment variable not set.\n");
00527 exit(1);
00528 }
00529 else
00530
00531 {
00532 if((display = XOpenDisplay(0)) == NULL)
00533 {
00534 printf("BC_WindowBase::init_display: cannot connect to default X server.\n");
00535 exit(1);
00536 }
00537 }
00538 }
00539 return display;
00540 }
00541
00542 int BC_WindowBase::run_window()
00543 {
00544 done = 0;
00545 return_value = 0;
00546
00547
00548
00549
00550
00551 if(window_type == MAIN_WINDOW)
00552 {
00553
00554 set_repeat(get_resources()->tooltip_delay);
00555 }
00556
00557
00558 event_thread = new BC_WindowEvents(this);
00559 event_thread->start();
00560
00561
00562 while(!done)
00563 {
00564 dispatch_event();
00565 }
00566
00567 unset_all_repeaters();
00568 hide_tooltip();
00569 delete event_thread;
00570 event_thread = 0;
00571 event_condition->reset();
00572 common_events.remove_all_objects();
00573 done = 0;
00574
00575 return return_value;
00576 }
00577
00578 int BC_WindowBase::get_key_masks(XEvent *event)
00579 {
00580
00581
00582
00583 ctrl_mask = (event->xkey.state & ControlMask) ? 1 : 0;
00584
00585 shift_mask = (event->xkey.state & ShiftMask) ? 1 : 0;
00586 alt_mask = (event->xkey.state & Mod1Mask) ? 1 : 0;
00587 return 0;
00588 }
00589
00590
00591
00592
00593
00594
00595
00596 int BC_WindowBase::dispatch_event()
00597 {
00598 XEvent *event = 0;
00599 Window tempwin;
00600 KeySym keysym;
00601 char keys_return[2];
00602 int result;
00603 XClientMessageEvent *ptr;
00604 int temp;
00605 int cancel_resize, cancel_translation;
00606
00607 key_pressed = 0;
00608
00609
00610
00611 if(get_event_count() ||
00612 (!motion_events && !resize_events && !translation_events))
00613 {
00614
00615 event = get_event();
00616
00617 lock_window("BC_WindowBase::dispatch_event 1");
00618
00619 }
00620 else
00621
00622 {
00623 lock_window("BC_WindowBase::dispatch_event 2");
00624 if(resize_events)
00625 dispatch_resize_event(last_resize_w, last_resize_h);
00626 else
00627 if(motion_events)
00628 dispatch_motion_event();
00629 else
00630 if(translation_events)
00631 dispatch_translation_event();
00632
00633 unlock_window();
00634 return 0;
00635 }
00636
00637
00638 switch(event->type)
00639 {
00640 case ClientMessage:
00641 get_key_masks(event);
00642
00643 if(resize_events) dispatch_resize_event(last_resize_w, last_resize_h);
00644
00645 if(motion_events)
00646 {
00647 dispatch_motion_event();
00648 }
00649
00650 ptr = (XClientMessageEvent*)event;
00651
00652
00653 if(ptr->message_type == ProtoXAtom &&
00654 ptr->data.l[0] == DelWinXAtom)
00655 {
00656 close_event();
00657 }
00658 else
00659 if(ptr->message_type == RepeaterXAtom)
00660 {
00661 dispatch_repeat_event(ptr->data.l[0]);
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 }
00672 else
00673 if(ptr->message_type == SetDoneXAtom)
00674 {
00675 done = 1;
00676 }
00677 break;
00678
00679 case FocusIn:
00680 has_focus = 1;
00681 dispatch_focus_in();
00682 break;
00683
00684 case FocusOut:
00685 has_focus = 0;
00686 dispatch_focus_out();
00687 break;
00688
00689
00690 case MapNotify:
00691 break;
00692
00693
00694 case UnmapNotify:
00695 break;
00696
00697 case ButtonPress:
00698 get_key_masks(event);
00699 cursor_x = event->xbutton.x;
00700 cursor_y = event->xbutton.y;
00701 button_number = event->xbutton.button;
00702 event_win = event->xany.window;
00703 if (button_number != 4 && button_number != 5)
00704 button_down = 1;
00705 button_pressed = event->xbutton.button;
00706 button_time1 = button_time2;
00707 button_time2 = event->xbutton.time;
00708 drag_x = cursor_x;
00709 drag_y = cursor_y;
00710 drag_win = event_win;
00711 drag_x1 = cursor_x - get_resources()->drag_radius;
00712 drag_x2 = cursor_x + get_resources()->drag_radius;
00713 drag_y1 = cursor_y - get_resources()->drag_radius;
00714 drag_y2 = cursor_y + get_resources()->drag_radius;
00715
00716 if(button_time2 - button_time1 < resources.double_click)
00717 {
00718
00719 double_click = 1;
00720 button_time2 = button_time1 = 0;
00721 }
00722 else
00723 double_click = 0;
00724
00725 dispatch_button_press();
00726 break;
00727
00728 case ButtonRelease:
00729 get_key_masks(event);
00730 button_number = event->xbutton.button;
00731 event_win = event->xany.window;
00732 if (button_number != 4 && button_number != 5)
00733 button_down = 0;
00734
00735 dispatch_button_release();
00736
00737 break;
00738
00739 case Expose:
00740 event_win = event->xany.window;
00741 dispatch_expose_event();
00742 break;
00743
00744 case MotionNotify:
00745 get_key_masks(event);
00746
00747 if(motion_events && last_motion_win != event->xany.window)
00748 {
00749 dispatch_motion_event();
00750 }
00751
00752
00753 motion_events = 1;
00754 last_motion_x = event->xmotion.x;
00755 last_motion_y = event->xmotion.y;
00756 last_motion_win = event->xany.window;
00757 break;
00758
00759 case ConfigureNotify:
00760 get_key_masks(event);
00761 XTranslateCoordinates(top_level->display,
00762 top_level->win,
00763 top_level->rootwin,
00764 0,
00765 0,
00766 &last_translate_x,
00767 &last_translate_y,
00768 &tempwin);
00769 last_resize_w = event->xconfigure.width;
00770 last_resize_h = event->xconfigure.height;
00771
00772 cancel_resize = 0;
00773 cancel_translation = 0;
00774
00775
00776 for(int i = 0; i < resize_history.total && !cancel_resize; i++)
00777 {
00778 if(resize_history.values[i]->w == last_resize_w &&
00779 resize_history.values[i]->h == last_resize_h)
00780 {
00781 delete resize_history.values[i];
00782 resize_history.remove_number(i);
00783 cancel_resize = 1;
00784 }
00785 }
00786
00787 if(last_resize_w == w && last_resize_h == h)
00788 cancel_resize = 1;
00789
00790 if(!cancel_resize)
00791 {
00792 resize_events = 1;
00793 }
00794
00795 if((last_translate_x == x && last_translate_y == y))
00796 cancel_translation = 1;
00797
00798 if(!cancel_translation)
00799 {
00800 translation_events = 1;
00801 }
00802
00803 translation_count++;
00804 break;
00805
00806 case KeyPress:
00807 get_key_masks(event);
00808 keys_return[0] = 0;
00809 XLookupString((XKeyEvent*)event, keys_return, 1, &keysym, 0);
00810
00811
00812
00813
00814 if(keysym > 0xffe0 && keysym < 0xffff) break;
00815
00816
00817 if(test_keypress) printf("BC_WindowBase::dispatch_event %x\n", keysym);
00818
00819
00820 switch(keysym)
00821 {
00822
00823 case XK_Alt_L:
00824 case XK_Alt_R:
00825 case XK_Shift_L:
00826 case XK_Shift_R:
00827 case XK_Control_L:
00828 case XK_Control_R:
00829 key_pressed = 0;
00830 break;
00831
00832
00833 case XK_Return: key_pressed = RETURN; break;
00834 case XK_Up: key_pressed = UP; break;
00835 case XK_Down: key_pressed = DOWN; break;
00836 case XK_Left: key_pressed = LEFT; break;
00837 case XK_Right: key_pressed = RIGHT; break;
00838 case XK_Next: key_pressed = PGDN; break;
00839 case XK_Prior: key_pressed = PGUP; break;
00840 case XK_BackSpace: key_pressed = BACKSPACE; break;
00841 case XK_Escape: key_pressed = ESC; break;
00842 case XK_Tab:
00843 if(shift_down())
00844 key_pressed = LEFTTAB;
00845 else
00846 key_pressed = TAB;
00847 break;
00848 case XK_ISO_Left_Tab: key_pressed = LEFTTAB; break;
00849 case XK_underscore: key_pressed = '_'; break;
00850 case XK_asciitilde: key_pressed = '~'; break;
00851 case XK_Delete: key_pressed = DELETE; break;
00852 case XK_Home: key_pressed = HOME; break;
00853 case XK_End: key_pressed = END; break;
00854
00855
00856 case XK_KP_Enter: key_pressed = KPENTER; break;
00857 case XK_KP_Add: key_pressed = KPPLUS; break;
00858 case XK_KP_1:
00859 case XK_KP_End: key_pressed = KP1; break;
00860 case XK_KP_2:
00861 case XK_KP_Down: key_pressed = KP2; break;
00862 case XK_KP_3:
00863 case XK_KP_Page_Down: key_pressed = KP3; break;
00864 case XK_KP_4:
00865 case XK_KP_Left: key_pressed = KP4; break;
00866 case XK_KP_5:
00867 case XK_KP_Begin: key_pressed = KP5; break;
00868 case XK_KP_6:
00869 case XK_KP_Right: key_pressed = KP6; break;
00870 case XK_KP_0:
00871 case XK_KP_Insert: key_pressed = KPINS; break;
00872 case XK_KP_Decimal:
00873 case XK_KP_Delete: key_pressed = KPDEL; break;
00874 default:
00875
00876 key_pressed = keysym & 0xff;
00877 break;
00878 }
00879
00880
00881 result = dispatch_keypress_event();
00882
00883 if(!result)
00884 {
00885 if(key_pressed == 'w' ||
00886 key_pressed == 'W')
00887 {
00888 close_event();
00889 }
00890 }
00891 break;
00892
00893 case LeaveNotify:
00894 event_win = event->xany.window;
00895 dispatch_cursor_leave();
00896 break;
00897
00898 case EnterNotify:
00899 event_win = event->xany.window;
00900 cursor_x = event->xcrossing.x;
00901 cursor_y = event->xcrossing.y;
00902 dispatch_cursor_enter();
00903 break;
00904 }
00905
00906
00907 unlock_window();
00908 if(event) delete event;
00909 return 0;
00910 }
00911
00912 int BC_WindowBase::dispatch_expose_event()
00913 {
00914 int result = 0;
00915 for(int i = 0; i < subwindows->total && !result; i++)
00916 {
00917 result = subwindows->values[i]->dispatch_expose_event();
00918 }
00919
00920
00921 if(!result) expose_event();
00922 return result;
00923 }
00924
00925 int BC_WindowBase::dispatch_resize_event(int w, int h)
00926 {
00927 if(window_type == MAIN_WINDOW)
00928 {
00929 resize_events = 0;
00930
00931
00932 XFreePixmap(top_level->display, pixmap);
00933 pixmap = XCreatePixmap(top_level->display,
00934 win,
00935 w,
00936 h,
00937 top_level->default_depth);
00938 clear_box(0, 0, w, h);
00939 }
00940
00941
00942 for(int i = 0; i < subwindows->total; i++)
00943 {
00944 subwindows->values[i]->dispatch_resize_event(w, h);
00945 }
00946
00947
00948 resize_event(w, h);
00949
00950 if(window_type == MAIN_WINDOW)
00951 {
00952 this->w = w;
00953 this->h = h;
00954 }
00955 return 0;
00956 }
00957
00958 int BC_WindowBase::dispatch_translation_event()
00959 {
00960 translation_events = 0;
00961 if(window_type == MAIN_WINDOW)
00962 {
00963 prev_x = x;
00964 prev_y = y;
00965 x = last_translate_x;
00966 y = last_translate_y;
00967
00968 x -= x_correction;
00969 y -= y_correction;
00970 }
00971
00972 for(int i = 0; i < subwindows->total; i++)
00973 {
00974 subwindows->values[i]->dispatch_translation_event();
00975 }
00976
00977 translation_event();
00978 return 0;
00979 }
00980
00981 int BC_WindowBase::dispatch_motion_event()
00982 {
00983 int result = 0;
00984
00985 if(top_level == this)
00986 {
00987 event_win = last_motion_win;
00988 motion_events = 0;
00989
00990
00991 if(get_button_down() && !active_menubar && !active_popup_menu)
00992 {
00993 if(!result)
00994 {
00995 cursor_x = last_motion_x;
00996 cursor_y = last_motion_y;
00997 result = dispatch_drag_motion();
00998 }
00999
01000 if(!result &&
01001 (last_motion_x < drag_x1 || last_motion_x >= drag_x2 ||
01002 last_motion_y < drag_y1 || last_motion_y >= drag_y2))
01003 {
01004 cursor_x = drag_x;
01005 cursor_y = drag_y;
01006
01007 result = dispatch_drag_start();
01008 }
01009 }
01010 cursor_x = last_motion_x;
01011 cursor_y = last_motion_y;
01012
01013 if(active_menubar && !result) result = active_menubar->dispatch_motion_event();
01014 if(active_popup_menu && !result) result = active_popup_menu->dispatch_motion_event();
01015 if(active_subwindow && !result) result = active_subwindow->dispatch_motion_event();
01016 }
01017
01018 for(int i = 0; i < subwindows->total && !result; i++)
01019 {
01020 result = subwindows->values[i]->dispatch_motion_event();
01021 }
01022
01023 if(!result) result = cursor_motion_event();
01024 return result;
01025 }
01026
01027 int BC_WindowBase::dispatch_keypress_event()
01028 {
01029 int result = 0;
01030 if(top_level == this)
01031 {
01032 if(active_subwindow) result = active_subwindow->dispatch_keypress_event();
01033 }
01034
01035 for(int i = 0; i < subwindows->total && !result; i++)
01036 {
01037 result = subwindows->values[i]->dispatch_keypress_event();
01038 }
01039
01040 if(!result) result = keypress_event();
01041
01042 return result;
01043 }
01044
01045 int BC_WindowBase::dispatch_focus_in()
01046 {
01047 for(int i = 0; i < subwindows->total; i++)
01048 {
01049 subwindows->values[i]->dispatch_focus_in();
01050 }
01051
01052 focus_in_event();
01053
01054 return 0;
01055 }
01056
01057 int BC_WindowBase::dispatch_focus_out()
01058 {
01059 for(int i = 0; i < subwindows->total; i++)
01060 {
01061 subwindows->values[i]->dispatch_focus_out();
01062 }
01063
01064 focus_out_event();
01065
01066 return 0;
01067 }
01068
01069 int BC_WindowBase::get_has_focus()
01070 {
01071 return top_level->has_focus;
01072 }
01073
01074 int BC_WindowBase::get_deleting()
01075 {
01076 if(is_deleting) return 1;
01077 if(parent_window && parent_window->get_deleting()) return 1;
01078 return 0;
01079 }
01080
01081 int BC_WindowBase::dispatch_button_press()
01082 {
01083 int result = 0;
01084 if(top_level == this)
01085 {
01086 if(active_menubar) result = active_menubar->dispatch_button_press();
01087 if(active_popup_menu && !result) result = active_popup_menu->dispatch_button_press();
01088 if(active_subwindow && !result) result = active_subwindow->dispatch_button_press();
01089 }
01090
01091 for(int i = 0; i < subwindows->total && !result; i++)
01092 {
01093 result = subwindows->values[i]->dispatch_button_press();
01094 }
01095
01096 if(!result) result = button_press_event();
01097
01098 return result;
01099 }
01100
01101 int BC_WindowBase::dispatch_button_release()
01102 {
01103 int result = 0;
01104 if(top_level == this)
01105 {
01106 if(active_menubar) result = active_menubar->dispatch_button_release();
01107
01108 if(active_popup_menu && !result) result = active_popup_menu->dispatch_button_release();
01109
01110 if(active_subwindow && !result) result = active_subwindow->dispatch_button_release();
01111
01112 if(!result && button_number != 4 && button_number != 5)
01113 result = dispatch_drag_stop();
01114 }
01115
01116
01117 for(int i = 0; i < subwindows->total && !result; i++)
01118 {
01119 result = subwindows->values[i]->dispatch_button_release();
01120 }
01121
01122
01123 if(!result)
01124 {
01125 result = button_release_event();
01126 }
01127
01128
01129 return result;
01130 }
01131
01132
01133 int BC_WindowBase::dispatch_repeat_event(int64_t duration)
01134 {
01135
01136
01137
01138 for(int i = 0; i < subwindows->total; i++)
01139 {
01140 subwindows->values[i]->dispatch_repeat_event(duration);
01141 }
01142 repeat_event(duration);
01143
01144
01145 if(window_type == MAIN_WINDOW)
01146 {
01147 for(int i = 0; i < repeaters.total; i++)
01148 {
01149 if(repeaters.values[i]->delay == duration)
01150 {
01151 repeaters.values[i]->repeat_lock->unlock();
01152 }
01153 }
01154 }
01155
01156 return 0;
01157 }
01158
01159 int BC_WindowBase::dispatch_cursor_leave()
01160 {
01161 for(int i = 0; i < subwindows->total; i++)
01162 {
01163 subwindows->values[i]->dispatch_cursor_leave();
01164 }
01165
01166 cursor_leave_event();
01167 return 0;
01168 }