/***************************************************************************
 * Copyright 1995, Technion, Israel Institute of Technology
 * Electrical Eng, Software Lab.
 * Author:    Michael Veksler.
 ***************************************************************************
 * File:      dde_proc.c
 * Purpose :  DDE signals and processes functionality for DDE
 ***************************************************************************
 */
#ifdef CONFIG_IPC

#if defined(__FreeBSD__) || defined(__NetBSD__)
#define msgbuf mymsg
#endif

#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/msg.h>
#include "wintypes.h"
#include "win.h"
#include "shm_semaph.h"
#include "shm_main_blk.h"
#include "dde_proc.h"
#include "dde_mem.h"
#include "dde.h"
#include "stddebug.h"
#include "debug.h"

int curr_proc_idx= -1;

enum stop_wait_op stop_wait_op=CONT;
int had_SIGUSR2 = 0;
sigjmp_buf env_get_ack;
sigjmp_buf env_wait_x;

#define IDX_TO_HWND(idx)  (0xfffe - (idx))
#define HWND_TO_IDX(wnd)  (0xfffe - (wnd))
#define DDE_WIN_INFO(win) ( main_block->windows[HWND_TO_IDX(win)] )
#define DDE_WIN2PROC(win) ( DDE_WIN_INFO(win).proc_idx )
#define DDE_IsRemoteWindow(win)	 (  (win)<0xffff && (win)>=(0xffff-DDE_PROCS))
#define DDE_SEND 1
#define DDE_POST 2
#define DDE_ACK	 3
#define DDE_MSG_SIZE   sizeof(MSG)
#define FREE_WND (WORD)(-2)
#define DELETED_WND (WORD)(-3)
#if defined(DEBUG_MSG) || defined(DEBUG_RUNTIME)
static char *msg_type[4]={"********", "DDE_SEND", "DDE_POST", "DDE_ACK"};
#endif

struct msg_dat {
	struct msgbuf dat;
	char filler[DDE_MSG_SIZE];
} ;

typedef struct fifo_element {
	int value;
	struct fifo_element *next;
} fifo_element;

struct fifo {
	fifo_element *first;	   /* first element in the fifo or NULL */
	fifo_element *last;	   /* last element in the fifo or NULL */
};
static struct fifo fifo = {NULL,NULL};

void dde_proc_delete(int proc_idx);

void dde_proc_add_fifo(int val)
{
  fifo_element *created;

  created= (fifo_element*) malloc( sizeof(fifo_element) );
  created->value = val;
  created->next = NULL;
  
  if (fifo.first==NULL) 
     fifo.first= created;
  else 
     fifo.last->next= created;
  fifo.last = created;
}

/* get an item from the fifo, and return it.
 * If fifo is empty, return -1
 */
int dde_proc_shift_fifo()
{
  int val;
  fifo_element *deleted;
  
  if (fifo.first == NULL)
     return -1;
  
  deleted= fifo.first;
  val= deleted->value;
  fifo.first= deleted->next;
  if (fifo.first == NULL)
     fifo.last= NULL;

  free(deleted);
  return val;
}

static void print_dde_message(char *desc, MSG *msg);

/* This should be run only when main_block is first allocated.	*/
void dde_proc_init(dde_proc proc)
{
  int proc_num;

  for (proc_num=0 ; proc_num<DDE_PROCS ; proc_num++, proc++) {
     proc->msg=-1;
     proc->sem=-1;
     proc->shmid=-1;
     proc->pid=-1;
  }
}

/* add current process to the list of processes */
void dde_proc_add(dde_proc procs)
{
  dde_proc proc;
  int proc_idx;
  dprintf_dde(stddeb,"dde_proc_add(..)\n");
  shm_write_wait(main_block->sem);

  /* find free proc_idx and allocate it */
  for (proc_idx=0, proc=procs ; proc_idx<DDE_PROCS ; proc_idx++, proc++)
     if (proc->pid==-1)
	break;			   /* found! */

  if (proc_idx<DDE_PROCS) {	   /* got here beacuse a free was found ? */
     dde_msg_setup(&proc->msg);
     proc->pid=getpid();
     curr_proc_idx=proc_idx;
     shm_sem_init(&proc->sem);
  }
  else	{
     fflush(stdout);
     fprintf(stderr,"dde_proc_add: Can't allocate process\n");
  }
  shm_write_signal(main_block->sem);
}

/* wait for dde - acknowledge message - or timout */
static BOOL get_ack()
{
    struct timeval timeout;
    int size;
    struct msg_dat ack_buff;

    /* timeout after exactly one seconf */
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    sigsetjmp(env_get_ack, 1);
    /* get here after normal execution, or after siglongjmp */

    do {			   /* loop to wait for DDE_ACK */
       had_SIGUSR2=0;
       stop_wait_op=CONT;	   /*  sensitive code: disallow siglongjmp */
       size= msgrcv( main_block->proc[curr_proc_idx].msg , &ack_buff.dat,
		     1, DDE_ACK, IPC_NOWAIT);
       if (size>=0) {
	  dprintf_msg(stddeb,"get_ack: received DDE_ACK message\n");
	  return TRUE;
       }
       if (DDE_GetRemoteMessage()) {
	     had_SIGUSR2=1;  /* might have recieved SIGUSR2 */
       }
       stop_wait_op=STOP_WAIT_ACK; /* allow siglongjmp */

    } while (had_SIGUSR2);	   /* loop if SIGUSR2 was recieved */

    /* siglongjmp should be enabled at this moment */
    select( 0, NULL, NULL, NULL, &timeout );
    stop_wait_op=CONT;		   /* disallow further siglongjmp */

    /* timeout !! (otherwise there would have been a siglongjmp) */
    return FALSE;
}

/* Transfer one message to a given process */
static BOOL DDE_DoOneMessage (int proc_idx, int size, struct msgbuf *msgbuf)
{
  dde_proc proc= &main_block->proc[ proc_idx ];


  if (proc_idx == curr_proc_idx)
     return FALSE;

  if (kill(proc->pid,0) < 0) {
     /* pid does not exist, or not our */
     dde_proc_delete(proc_idx);
     return FALSE;
  }

  if (debugging_dde) {
     MSG *msg=(MSG*) &msgbuf->mtext;
     char *title;
     if (msgbuf->mtype==DDE_SEND)
	title="sending dde:";
     else if (msgbuf->mtype==DDE_POST)
	title="posting dde:";
     else
	title=NULL;
     if (title)
	 print_dde_message(title, msg);
     else
       fprintf(stddeb,"Unknown message type=0x%lx\n",msgbuf->mtype);
  }
  dprintf_msg(stddeb,
	      "DDE_DoOneMessage: to proc_idx=%d (pid=%d), queue=%u\n",
	      proc_idx, proc->pid, (unsigned)proc->msg);
  if ( proc->msg != -1) {
     dprintf_msg(stddeb, "DDE_DoOneMessage: doing...(type=%s)\n",
		 msg_type[msgbuf->mtype]);
     size=msgsnd (proc->msg, msgbuf, size, 0);

     if (size<0) {
	 fflush(stdout);
	 perror("msgsnd");
     }
     kill(proc->pid,SIGUSR2);	   /* tell the process there is a message */

     dprintf_msg(stddeb,"DDE_DoOneMessage: "
		 "Trying to get acknowledgment from msg queue=%d\n",
		 proc->msg);
     Yield();			/* force task switch, and */
				/* acknowledgment sending */
     if (get_ack()) {
	return TRUE;
     } else {
	fflush(stdout);
	fprintf(stderr,"get_ack: DDE_DoOneMessage: timeout\n");
	return FALSE;
     }
  }
  else {
     dprintf_msg(stddeb,"DDE_DoOneMessage: message not sent, "
		 "target has no message queue\n");
     return FALSE;
  }
}

/* Do some sort of premitive hash table */
static HWND HWND_Local2Remote(HWND orig)
{
  int dde_wnd_idx;
  int deleted_idx= -1;
  WND_DATA *tested;
  WND_DATA *deleted= NULL;
  int i;
  
  dde_wnd_idx= orig % DDE_WINDOWS;
  for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
    if (dde_wnd_idx >= DDE_WINDOWS)
      dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
    
    tested= &main_block->windows[ dde_wnd_idx ];
    if (tested->proc_idx == FREE_WND)
      break;
    
    if (deleted == NULL && tested->proc_idx == DELETED_WND) {
      deleted= tested;
      deleted_idx= dde_wnd_idx;
    } else if (tested->wnd == orig && tested->proc_idx == curr_proc_idx) {
      return IDX_TO_HWND(dde_wnd_idx);
    }
  }
  if (deleted != NULL)	{	/* deleted is preferable */
    /* free item, allocate it */
    deleted->proc_idx= curr_proc_idx;
    deleted->wnd = orig;
    return IDX_TO_HWND(deleted_idx);
  }
  if (tested->proc_idx == FREE_WND) {
    tested->proc_idx= curr_proc_idx;
    tested->wnd = orig;
    return IDX_TO_HWND(dde_wnd_idx);
  }

  fprintf(stderr,
	  "HWND_Local2Remote: Can't map any more windows to DDE windows\n");
  return 0;			
}

static BOOL DDE_DoMessage( MSG *msg, int type )
{
  int proc_idx;

  MSG *remote_message;
  struct msg_dat msg_dat;
  BOOL success;
  
  if (msg->wParam == 0)
      return FALSE;
  
  if (main_block==NULL) {
    if (msg->message >=  WM_DDE_FIRST && msg->message <= WM_DDE_LAST) 
      DDE_IPC_init();
    else 
      return FALSE;
  }


  if (msg->wParam == (HWND)-1)
     return FALSE;

  if ( ! DDE_IsRemoteWindow(msg->hwnd) && msg->hwnd!= (HWND)-1)
     return FALSE;

  dprintf_msg(stddeb, "%s: DDE_DoMessage(hwnd=0x%x,msg=0x%x,..)\n",
	      msg_type[type], (int)msg->hwnd,(int)msg->message);


  dprintf_msg(stddeb,
	      "DDE_DoMessage(hwnd=0x%x,msg=0x%x,..) // HWND_BROADCAST !\n",
	      (int)msg->hwnd,(int)msg->message);
  remote_message=(void*)&msg_dat.dat.mtext;
  
  memcpy(remote_message, msg, sizeof(*msg));
  remote_message->wParam= HWND_Local2Remote(msg->wParam);
  if (remote_message->wParam == 0)
    return FALSE;
  
  msg_dat.dat.mtype=type;

  if (msg->hwnd == (HWND)-1) {
     success= FALSE;
     for ( proc_idx=0; proc_idx < DDE_PROCS ; proc_idx++) {
	if (proc_idx == curr_proc_idx)
	   continue;
	if (main_block->proc[ proc_idx ].msg != -1)
	   success|=DDE_DoOneMessage(proc_idx, DDE_MSG_SIZE, &msg_dat.dat);
     }
     return success;
  } else {
     return DDE_DoOneMessage(DDE_WIN2PROC(msg->hwnd), DDE_MSG_SIZE,
			     &msg_dat.dat);
  }
}

BOOL DDE_SendMessage( MSG *msg)
{
  return DDE_DoMessage(msg, DDE_SEND);
}

BOOL DDE_PostMessage( MSG *msg)
{
  return DDE_DoMessage(msg, DDE_POST);
}


void dde_proc_send_ack(HWND wnd, BOOL val) {
   int proc,msg;

   static struct msgbuf msg_ack={DDE_ACK,{'0'}};

   proc=DDE_WIN2PROC(wnd);
   msg=main_block->proc[proc].msg;
   dprintf_msg(stddeb,"DDE_GetRemoteMessage: sending ACK "
	       "to wnd=%4x, proc=%d,msg=%d, pid=%d\n",wnd,proc,msg,
	       main_block->proc[proc].pid
     );

   msg_ack.mtext[0]=val;
   msgsnd (msg, &msg_ack, 1, 0);
   kill(main_block->proc[proc].pid, SIGUSR2);
}

/* return true (non zero) if had a remote message */
#undef DDE_GetRemoteMessage

int DDE_GetRemoteMessage()
{
  static int nesting=0;		   /* to avoid infinite recursion */

  MSG *remote_message;
  int size;
  struct msg_dat msg_dat;
  BOOL was_sent;		   /* sent/received */
  BOOL passed;
  HWND hwnd;
  WND	*window;

  if (curr_proc_idx==-1)	   /* do we have DDE initialized ? */
     return 0;

  if (nesting>10) {
     fflush(stdout);
     fprintf(stderr,"DDE_GetRemoteMessage: suspecting infinite recursion, exiting");
     return 0;
  }

  remote_message=(void*)&msg_dat.dat.mtext;

  /* test for SendMessage */
  size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
		DDE_MSG_SIZE, DDE_SEND, IPC_NOWAIT);

  if (size==DDE_MSG_SIZE) {	   /* is this a correct message (if any) ?*/
     was_sent=TRUE;
     dprintf_msg(stddeb,
		 "DDE:receive sent message. msg=%04x wPar=%04x"
		 " lPar=%08lx\n",
		 remote_message->message, remote_message->wParam,
		 remote_message->lParam);
  } else {
     size= msgrcv( main_block->proc[curr_proc_idx].msg , &msg_dat.dat,
		   DDE_MSG_SIZE, DDE_POST, IPC_NOWAIT);

     if (size==DDE_MSG_SIZE) {	   /* is this a correct message (if any) ?*/
	was_sent=FALSE;
	dprintf_msg(stddeb,
		    "DDE:receive posted message. "
		    "msg=%04x wPar=%04x lPar=%08lx\n",
		    remote_message->message, remote_message->wParam,
		    remote_message->lParam);
     }
     else
	return 0;		   /* no DDE message found */
  }

  /* At this point we are sure that there is a DDE message,
   * was_sent is TRUE is the message was sent, and false if it was posted
   */

  nesting++;

  if (debugging_dde) {
     char *title;
     if (was_sent)
	title="receive sent dde:";
     else
	title="receive posted dde:";
     print_dde_message(title, remote_message);
  }

  if (remote_message->hwnd != (HWND) -1 ) {
    HWND dde_window= DDE_WIN_INFO(remote_message->hwnd).wnd;
     /* we should know exactly where to send the message (locally)*/
     if (was_sent) {
	dprintf_dde(stddeb,
		    "SendMessage(wnd=0x%04x, msg=0x%04x, wPar=0x%04x,"
		    "lPar=0x%08x\n",
		    dde_window, remote_message->message,
		    remote_message->wParam, (int)remote_message->lParam);

	/* execute the recieved message */
	passed= SendMessage(dde_window, remote_message->message,
			    remote_message->wParam, remote_message->lParam);

	/* Tell the sended, that the message is here */
	dde_proc_send_ack(remote_message->wParam, passed);
     }
     else {
	passed= PostMessage(dde_window, remote_message->message,
			    remote_message->wParam, remote_message->lParam);
	if (passed == FALSE) {
	   /* Tell the sender, that the message is here, and failed */
	    dde_proc_send_ack(remote_message->wParam, FALSE);
	}
	else {
	   /* ack will be sent later, at the first peek/get message  */
	   dde_proc_add_fifo(remote_message->wParam);
	}
     }
     nesting--;
     return 1;
  }

  /* iterate through all the windows */
  for (hwnd = GetTopWindow(GetDesktopWindow());
       hwnd && (window = WIN_FindWndPtr(hwnd))!=NULL ;
       hwnd = window->hwndNext) {
     if (window->dwStyle & WS_POPUP || window->dwStyle & WS_CAPTION) {
	if (was_sent)
	   SendMessage( hwnd, remote_message->message,
			remote_message->wParam, remote_message->lParam );
	else
	   PostMessage( hwnd, remote_message->message,
		     remote_message->wParam, remote_message->lParam );
     } /* if */
  } /* for */

  /* replay with DDE_ACK after broadcasting in DDE_GetRemoteMessage */
  dde_proc_send_ack(remote_message->wParam, TRUE);

  nesting--;
  return 1;
}

int dde_reschedule()
{
    int ack_wnd;
	
    ack_wnd= dde_proc_shift_fifo();
    if (ack_wnd != -1) {
	dde_proc_send_ack(ack_wnd, TRUE);
	usleep(10000);		/* force unix task switch */
	return 1;
    }
    return 0;
}
void dde_msg_setup(int *msg_ptr)
{
  *msg_ptr= msgget (IPC_PRIVATE, IPC_CREAT | 0700);
  if (*msg_ptr==-1)
     perror("dde_msg_setup fails to get message queue");
}

/* do we have dde handling in the window ?
 * If we have, atom usage will make this instance of wine set up
 * it's IPC stuff.
 */
void DDE_TestDDE(HWND hwnd)	   
{

  if (main_block != NULL)
     return;
  dprintf_msg(stddeb,"DDE_TestDDE(0x%04x)\n", hwnd);
  if (hwnd==0)
      hwnd=-1;
  /* just send a message to see how things are going */
  SendMessage( hwnd, WM_DDE_INITIATE, 0, 0);
}

void dde_proc_delete(int proc_idx)
{
  dde_proc_done(&main_block->proc[proc_idx]);
}
void stop_wait(int a)
{

  had_SIGUSR2=1;
  switch(stop_wait_op) {
    case STOP_WAIT_ACK:
      siglongjmp(env_get_ack,1);
      break;  /* never reached */
    case STOP_WAIT_X:
      siglongjmp(env_wait_x,1);
      break;  /* never reached */
    case CONT:
      /* do nothing */
  }
}

static void print_dde_message(char *desc, MSG *msg)
{
    extern const char *MessageTypeNames[];
    extern int debug_last_handle_size;
    WORD wStatus,hWord;
    void *ptr;
    DDEACK *ddeack;
    DDEADVISE *ddeadvise;
    DDEDATA *ddedata;
    DDEPOKE *ddepoke;

    if (is_dde_handle(msg->lParam & 0xffff) )
	ptr=DDE_AttachHandle(msg->lParam&0xffff, NULL);
    else
	ptr =NULL;
    wStatus=LOWORD(msg->lParam);
    hWord=HIWORD(msg->lParam);

    fprintf(stddeb,"%s", desc);
    fprintf(stddeb,"%04x %04x==%s %04x %08lx ",
	    msg->hwnd, msg->message,MessageTypeNames[msg->message],
	    msg->wParam, msg->lParam);
    switch(msg->message) {
      case WM_DDE_INITIATE:
      case WM_DDE_REQUEST:
      case WM_DDE_EXECUTE:
      case WM_DDE_TERMINATE:
	/* nothing to do */
	break;
      case WM_DDE_ADVISE:
	/* DDEADVISE: hOptions in WM_DDE_ADVISE message */
	if (ptr) {
	   ddeadvise=ptr;
	   fprintf(stddeb,"fDeferUpd=%d,fAckReq=%d,cfFormat=0x%x",
		   ddeadvise->fDeferUpd, ddeadvise->fAckReq,
		   ddeadvise->cfFormat);
	} else
	   fprintf(stddeb,"NO-DATA");
	fprintf(stddeb," atom=0x%x",hWord);
	break;

      case WM_DDE_UNADVISE:
	fprintf(stddeb,"format=0x%x, atom=0x%x",wStatus,hWord);
	break;
      case WM_DDE_ACK:
	ddeack=(DDEACK*)&wStatus;
	fprintf(stddeb,"bAppReturnCode=%d,fBusy=%d,fAck=%d",
		ddeack->bAppReturnCode, ddeack->fBusy, ddeack->fAck);
	if (ddeack->fAck)
	   fprintf(stddeb,"(True)");
	else
	   fprintf(stddeb,"(False)");
	break;

      case WM_DDE_DATA:
	if (ptr) {
	   ddedata=ptr;
	   fprintf(stddeb,"fResponse=%d,fRelease=%d,"
		   "fAckReq=%d,cfFormat=0x%x,value=\"%.*s\"",
		   ddedata->fResponse, ddedata->fRelease,
		   ddedata->fAckReq, ddedata->cfFormat,
		   debug_last_handle_size- (int)sizeof(*ddedata)+1,
		   ddedata->Value);
	} else
	   fprintf(stddeb,"NO-DATA");
	fprintf(stddeb," atom=0x%04x",hWord);
	break;

      case WM_DDE_POKE:
	if (ptr) {
	   ddepoke=ptr;
	   fprintf(stddeb,"fRelease=%d,cfFormat=0x%x,value[0]='%c'",
		   ddepoke->fRelease, ddepoke->cfFormat, ddepoke->Value[0]);
	} else
	   fprintf(stddeb,"NO-DATA");
	fprintf(stddeb," atom=0x%04x",hWord);
	break;
    }
    fprintf(stddeb,"\n");
}

void dde_proc_done(dde_proc proc)
{
  if (proc->msg != -1)
     msgctl(proc->msg, IPC_RMID, NULL);
  proc->msg=-1;
  proc->pid=-1;
  shm_delete_chain(&proc->shmid);
  shm_sem_done(&proc->sem);
}

/* delete entry, if old junk */
void dde_proc_refresh(dde_proc proc)
{
  if (proc->pid == -1)		  
     return;
  
  if (kill(proc->pid, 0) != -1)
     return;

  /* get here if entry non empty, and the process does not exist */
  dde_proc_done(proc);
}

void dde_wnd_setup()
{
  int i;

  for (i=0 ; i < DDE_WINDOWS ; i++)
    main_block->windows[i].proc_idx = FREE_WND;
}

static BOOL DDE_ProcHasWindows(int proc_idx)
{
  WND_DATA *tested;
  int i;
  
  for ( i=0 ; i < DDE_WINDOWS ; i++) {
    tested= &main_block->windows[ i ];
    
    if (tested->proc_idx == proc_idx) 
      return TRUE;
  }
  return FALSE;
}
/* Look for hwnd in the hash table of DDE windows,
 * Delete it from there. If there are no more windows for this
 * process, remove the process from the DDE data-structure.
 * If there are no more processes - delete the whole DDE struff.
 *
 * This is inefficient, but who cares for the efficiency of this rare
 * operation... 
 */
void DDE_DestroyWindow(HWND hwnd)
{
  int dde_wnd_idx;
  WND_DATA *tested;
  int i;
  
  if (main_block == NULL)
    return;
  
  dde_wnd_idx= hwnd % DDE_WINDOWS;
  
  for ( i=0 ; i < DDE_WINDOWS ; i++, dde_wnd_idx++) {
    if (dde_wnd_idx >= DDE_WINDOWS)
      dde_wnd_idx -= DDE_WINDOWS; /* wrap-around */
    
    tested= &main_block->windows[ dde_wnd_idx ];
    if (tested->proc_idx == FREE_WND)
      return;			/* No window will get deleted here */
    
    if (tested->wnd == hwnd && tested->proc_idx == curr_proc_idx) {
      dde_reschedule();
      tested->proc_idx= DELETED_WND;
      if (DDE_ProcHasWindows( curr_proc_idx ))
	return;
      while (dde_reschedule())	/* make sure there are no other */
				/* processes waiting for acknowledgment */
	;
      dde_proc_delete( curr_proc_idx );
      if (DDE_no_of_attached() == 1)
	shm_delete_all(-1);
      else {
	shmdt( (void *) main_block);
	main_block= NULL;
      }
      return;
    }
  }
}

#endif  /* CONFIG_IPC */
